diff --git a/authmate/authmate.go b/authmate/authmate.go index 71ad1ed..e4cd5ef 100644 --- a/authmate/authmate.go +++ b/authmate/authmate.go @@ -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 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 { diff --git a/cmd/authmate/main.go b/cmd/authmate/main.go index cda41d5..df4226c 100644 --- a/cmd/authmate/main.go +++ b/cmd/authmate/main.go @@ -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),