[#364] Support placement policy overriding
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
4454821285
commit
6a4fba4d09
2 changed files with 54 additions and 69 deletions
|
@ -54,8 +54,7 @@ type (
|
|||
|
||||
// IssueSecretOptions contains options for passing to Agent.IssueSecret method.
|
||||
IssueSecretOptions struct {
|
||||
ContainerID *cid.ID
|
||||
ContainerFriendlyName string
|
||||
Container ContainerOptions
|
||||
NeoFSKey *keys.PrivateKey
|
||||
GatesPublicKeys []*keys.PublicKey
|
||||
EACLRules []byte
|
||||
|
@ -65,6 +64,13 @@ type (
|
|||
ContainerPolicies ContainerPolicies
|
||||
}
|
||||
|
||||
// ContainerOptions groups parameters of auth container to put the secret into.
|
||||
ContainerOptions struct {
|
||||
ID *cid.ID
|
||||
FriendlyName string
|
||||
PlacementPolicy string
|
||||
}
|
||||
|
||||
// ObtainSecretOptions contains options for passing to Agent.ObtainSecret method.
|
||||
ObtainSecretOptions struct {
|
||||
SecretAddress string
|
||||
|
@ -98,14 +104,14 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
func (a *Agent) checkContainer(ctx context.Context, cid *cid.ID, friendlyName string) (*cid.ID, error) {
|
||||
if cid != nil {
|
||||
func (a *Agent) checkContainer(ctx context.Context, opts ContainerOptions) (*cid.ID, error) {
|
||||
if opts.ID != nil {
|
||||
// check that container exists
|
||||
_, err := a.pool.GetContainer(ctx, cid)
|
||||
return cid, err
|
||||
_, err := a.pool.GetContainer(ctx, opts.ID)
|
||||
return opts.ID, err
|
||||
}
|
||||
|
||||
pp, err := buildPlacementPolicy("")
|
||||
pp, err := policy.Parse(opts.PlacementPolicy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build placement policy: %w", err)
|
||||
}
|
||||
|
@ -115,24 +121,24 @@ func (a *Agent) checkContainer(ctx context.Context, cid *cid.ID, friendlyName st
|
|||
container.WithCustomBasicACL(defaultAuthContainerBasicACL),
|
||||
container.WithAttribute(container.AttributeTimestamp, strconv.FormatInt(time.Now().Unix(), 10)),
|
||||
}
|
||||
if friendlyName != "" {
|
||||
cnrOptions = append(cnrOptions, container.WithAttribute(container.AttributeName, friendlyName))
|
||||
if opts.FriendlyName != "" {
|
||||
cnrOptions = append(cnrOptions, container.WithAttribute(container.AttributeName, opts.FriendlyName))
|
||||
}
|
||||
|
||||
cnr := container.New(cnrOptions...)
|
||||
if friendlyName != "" {
|
||||
container.SetNativeName(cnr, friendlyName)
|
||||
if opts.FriendlyName != "" {
|
||||
container.SetNativeName(cnr, opts.FriendlyName)
|
||||
}
|
||||
|
||||
cid, err = a.pool.PutContainer(ctx, cnr)
|
||||
cnrID, err := a.pool.PutContainer(ctx, cnr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := a.pool.WaitForContainerPresence(ctx, cid, pool.DefaultPollingParams()); err != nil {
|
||||
if err := a.pool.WaitForContainerPresence(ctx, cnrID, pool.DefaultPollingParams()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cid, nil
|
||||
return cnrID, nil
|
||||
}
|
||||
|
||||
func (a *Agent) getEpochDurations(ctx context.Context) (*epochDurations, error) {
|
||||
|
@ -235,8 +241,10 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
|||
lifetime.Exp = lifetime.Iat + epochLifetime
|
||||
}
|
||||
|
||||
a.log.Info("check container", zap.Stringer("cid", options.ContainerID))
|
||||
if cid, err = a.checkContainer(ctx, options.ContainerID, options.ContainerFriendlyName); err != nil {
|
||||
a.log.Info("check container or create", zap.Stringer("cid", options.Container.ID),
|
||||
zap.String("friendly_name", options.Container.FriendlyName),
|
||||
zap.String("placement_policy", options.Container.PlacementPolicy))
|
||||
if cid, err = a.checkContainer(ctx, options.Container); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -321,40 +329,6 @@ func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSe
|
|||
return enc.Encode(or)
|
||||
}
|
||||
|
||||
func buildPlacementPolicy(placementRules string) (*netmap.PlacementPolicy, error) {
|
||||
if len(placementRules) != 0 {
|
||||
return policy.Parse(placementRules)
|
||||
}
|
||||
|
||||
/*
|
||||
REP 2 IN X // place two copies of object
|
||||
CBF 3
|
||||
SELECT 2 From * AS X // in container of two nodes
|
||||
*/
|
||||
pp := new(netmap.PlacementPolicy)
|
||||
pp.SetContainerBackupFactor(3)
|
||||
pp.SetReplicas([]*netmap.Replica{newReplica("X", 2)}...)
|
||||
pp.SetSelectors([]*netmap.Selector{newSimpleSelector("X", 2)}...)
|
||||
|
||||
return pp, nil
|
||||
}
|
||||
|
||||
// selects <count> nodes in container without any additional attributes.
|
||||
func newSimpleSelector(name string, count uint32) (s *netmap.Selector) {
|
||||
s = new(netmap.Selector)
|
||||
s.SetCount(count)
|
||||
s.SetFilter("*")
|
||||
s.SetName(name)
|
||||
return
|
||||
}
|
||||
|
||||
func newReplica(name string, count uint32) (r *netmap.Replica) {
|
||||
r = new(netmap.Replica)
|
||||
r.SetCount(count)
|
||||
r.SetSelector(name)
|
||||
return
|
||||
}
|
||||
|
||||
func buildEACLTable(cid *cid.ID, eaclTable []byte) (*eacl.Table, error) {
|
||||
table := eacl.NewTable()
|
||||
if len(eaclTable) != 0 {
|
||||
|
|
|
@ -32,23 +32,24 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
walletPathFlag string
|
||||
accountAddressFlag string
|
||||
peerAddressFlag string
|
||||
eaclRulesFlag string
|
||||
gateWalletPathFlag string
|
||||
gateAccountAddressFlag string
|
||||
accessKeyIDFlag string
|
||||
containerIDFlag string
|
||||
containerFriendlyName string
|
||||
gatesPublicKeysFlag cli.StringSlice
|
||||
logEnabledFlag bool
|
||||
logDebugEnabledFlag bool
|
||||
sessionTokenFlag string
|
||||
lifetimeFlag time.Duration
|
||||
containerPolicies string
|
||||
awcCliCredFile string
|
||||
timeoutFlag time.Duration
|
||||
walletPathFlag string
|
||||
accountAddressFlag string
|
||||
peerAddressFlag string
|
||||
eaclRulesFlag string
|
||||
gateWalletPathFlag string
|
||||
gateAccountAddressFlag string
|
||||
accessKeyIDFlag string
|
||||
containerIDFlag string
|
||||
containerFriendlyName string
|
||||
containerPlacementPolicy string
|
||||
gatesPublicKeysFlag cli.StringSlice
|
||||
logEnabledFlag bool
|
||||
logDebugEnabledFlag bool
|
||||
sessionTokenFlag string
|
||||
lifetimeFlag time.Duration
|
||||
containerPolicies string
|
||||
awcCliCredFile string
|
||||
timeoutFlag time.Duration
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -191,6 +192,13 @@ func issueSecret() *cli.Command {
|
|||
Required: false,
|
||||
Destination: &containerFriendlyName,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "container-placement-policy",
|
||||
Usage: "placement policy of auth container to put the secret into",
|
||||
Required: false,
|
||||
Destination: &containerPlacementPolicy,
|
||||
Value: "REP 2 IN X CBF 3 SELECT 2 FROM * AS X",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "session-token",
|
||||
Usage: "create session token with rules, if the rules are set as 'none', no session tokens will be created",
|
||||
|
@ -264,8 +272,11 @@ It will be ceil rounded to the nearest amount of epoch.`,
|
|||
}
|
||||
|
||||
issueSecretOptions := &authmate.IssueSecretOptions{
|
||||
ContainerID: containerID,
|
||||
ContainerFriendlyName: containerFriendlyName,
|
||||
Container: authmate.ContainerOptions{
|
||||
ID: containerID,
|
||||
FriendlyName: containerFriendlyName,
|
||||
PlacementPolicy: containerPlacementPolicy,
|
||||
},
|
||||
NeoFSKey: key,
|
||||
GatesPublicKeys: gatesPublicKeys,
|
||||
EACLRules: getJSONRules(eaclRulesFlag),
|
||||
|
|
Loading…
Reference in a new issue