diff --git a/api/credentiallibraries/credential_library.gen.go b/api/credentiallibraries/credential_library.gen.go index 4eb7d8cee..ba315aa1c 100644 --- a/api/credentiallibraries/credential_library.gen.go +++ b/api/credentiallibraries/credential_library.gen.go @@ -90,7 +90,7 @@ func (c *Client) ApiClient() *api.Client { return c.client } -func (c *Client) Create(ctx context.Context, credentialStoreId string, opt ...Option) (*CredentialLibraryCreateResult, error) { +func (c *Client) Create(ctx context.Context, resourceType string, credentialStoreId string, opt ...Option) (*CredentialLibraryCreateResult, error) { if credentialStoreId == "" { return nil, fmt.Errorf("empty credentialStoreId value passed into Create request") } @@ -100,6 +100,11 @@ func (c *Client) Create(ctx context.Context, credentialStoreId string, opt ...Op if c.client == nil { return nil, fmt.Errorf("nil client") } + if resourceType == "" { + return nil, fmt.Errorf("empty resourceType value passed into Create request") + } else { + opts.postMap["type"] = resourceType + } opts.postMap["credential_store_id"] = credentialStoreId diff --git a/api/credentiallibraries/option.gen.go b/api/credentiallibraries/option.gen.go index c63590351..12ba34836 100644 --- a/api/credentiallibraries/option.gen.go +++ b/api/credentiallibraries/option.gen.go @@ -110,6 +110,30 @@ func DefaultCredentialType() Option { } } +func WithVaultSSHCertificateCredentialLibraryCriticalOptions(inCriticalOptions map[string]string) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["critical_options"] = inCriticalOptions + o.postMap["attributes"] = val + } +} + +func DefaultVaultSSHCertificateCredentialLibraryCriticalOptions() Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["critical_options"] = nil + o.postMap["attributes"] = val + } +} + func WithDescription(inDescription string) Option { return func(o *options) { o.postMap["description"] = inDescription @@ -122,6 +146,30 @@ func DefaultDescription() Option { } } +func WithVaultSSHCertificateCredentialLibraryExtensions(inExtensions map[string]string) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["extensions"] = inExtensions + o.postMap["attributes"] = val + } +} + +func DefaultVaultSSHCertificateCredentialLibraryExtensions() Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["extensions"] = nil + o.postMap["attributes"] = val + } +} + func WithVaultCredentialLibraryHttpMethod(inHttpMethod string) Option { return func(o *options) { raw, ok := o.postMap["attributes"] @@ -170,6 +218,78 @@ func DefaultVaultCredentialLibraryHttpRequestBody() Option { } } +func WithVaultSSHCertificateCredentialLibraryKeyBits(inKeyBits uint32) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["key_bits"] = inKeyBits + o.postMap["attributes"] = val + } +} + +func DefaultVaultSSHCertificateCredentialLibraryKeyBits() Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["key_bits"] = nil + o.postMap["attributes"] = val + } +} + +func WithVaultSSHCertificateCredentialLibraryKeyId(inKeyId string) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["key_id"] = inKeyId + o.postMap["attributes"] = val + } +} + +func DefaultVaultSSHCertificateCredentialLibraryKeyId() Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["key_id"] = nil + o.postMap["attributes"] = val + } +} + +func WithVaultSSHCertificateCredentialLibraryKeyType(inKeyType string) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["key_type"] = inKeyType + o.postMap["attributes"] = val + } +} + +func DefaultVaultSSHCertificateCredentialLibraryKeyType() Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["key_type"] = nil + o.postMap["attributes"] = val + } +} + func WithName(inName string) Option { return func(o *options) { o.postMap["name"] = inName @@ -193,3 +313,51 @@ func WithVaultCredentialLibraryPath(inPath string) Option { o.postMap["attributes"] = val } } + +func WithVaultSSHCertificateCredentialLibraryPath(inPath string) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["path"] = inPath + o.postMap["attributes"] = val + } +} + +func WithVaultSSHCertificateCredentialLibraryTtl(inTtl string) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["ttl"] = inTtl + o.postMap["attributes"] = val + } +} + +func DefaultVaultSSHCertificateCredentialLibraryTtl() Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["ttl"] = nil + o.postMap["attributes"] = val + } +} + +func WithVaultSSHCertificateCredentialLibraryUsername(inUsername string) Option { + return func(o *options) { + raw, ok := o.postMap["attributes"] + if !ok { + raw = interface{}(map[string]interface{}{}) + } + val := raw.(map[string]interface{}) + val["username"] = inUsername + o.postMap["attributes"] = val + } +} diff --git a/api/credentiallibraries/vault_ssh_certificate_credential_library_attributes.gen.go b/api/credentiallibraries/vault_ssh_certificate_credential_library_attributes.gen.go new file mode 100644 index 000000000..534e6f2f2 --- /dev/null +++ b/api/credentiallibraries/vault_ssh_certificate_credential_library_attributes.gen.go @@ -0,0 +1,44 @@ +// Code generated by "make api"; DO NOT EDIT. +package credentiallibraries + +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + +type VaultSSHCertificateCredentialLibraryAttributes struct { + Path string `json:"path,omitempty"` + Username string `json:"username,omitempty"` + KeyType string `json:"key_type,omitempty"` + KeyBits uint32 `json:"key_bits,omitempty"` + Ttl string `json:"ttl,omitempty"` + KeyId string `json:"key_id,omitempty"` + CriticalOptions map[string]string `json:"critical_options,omitempty"` + Extensions map[string]string `json:"extensions,omitempty"` +} + +func AttributesMapToVaultSSHCertificateCredentialLibraryAttributes(in map[string]interface{}) (*VaultSSHCertificateCredentialLibraryAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out VaultSSHCertificateCredentialLibraryAttributes + dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + Result: &out, + TagName: "json", + }) + if err != nil { + return nil, fmt.Errorf("error creating mapstructure decoder: %w", err) + } + if err := dec.Decode(in); err != nil { + return nil, fmt.Errorf("error decoding: %w", err) + } + return &out, nil +} + +func (pt *CredentialLibrary) GetVaultSSHCertificateCredentialLibraryAttributes() (*VaultSSHCertificateCredentialLibraryAttributes, error) { + if pt.Type != "vaultsshcertificate" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but credential-library is of type %s", "vaultsshcertificate", pt.Type) + } + return AttributesMapToVaultSSHCertificateCredentialLibraryAttributes(pt.Attributes) +} diff --git a/internal/api/genapi/input.go b/internal/api/genapi/input.go index ad660b226..807cebb10 100644 --- a/internal/api/genapi/input.go +++ b/internal/api/genapi/input.go @@ -518,12 +518,58 @@ var inputStructs = []*structInfo{ mapstructureConversionTemplate, }, }, + { + inProto: &credentiallibraries.VaultSSHCertificateCredentialLibraryAttributes{}, + outFile: "credentiallibraries/vault_ssh_certificate_credential_library_attributes.gen.go", + subtypeName: "VaultSSHCertificateCredentialLibrary", + fieldOverrides: []fieldInfo{ + { + Name: "Path", + SkipDefault: true, + }, + { + Name: "Username", + SkipDefault: true, + }, + { + Name: "CriticalOptions", + FieldType: "map[string]string", + }, + { + Name: "Extensions", + FieldType: "map[string]string", + }, + }, + parentTypeName: "CredentialLibrary", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, + }, { inProto: &credentiallibraries.CredentialLibrary{}, outFile: "credentiallibraries/credential_library.gen.go", templates: []*template.Template{ clientTemplate, - commonCreateTemplate, + template.Must(template.New("").Funcs( + template.FuncMap{ + "snakeCase": snakeCase, + "funcName": func() string { + return "Create" + }, + "apiAction": func() string { + return "" + }, + "extraRequiredParams": func() []requiredParam { + return []requiredParam{ + { + Name: "resourceType", + Typ: "string", + PostType: "type", + }, + } + }, + }, + ).Parse(createTemplateStr)), readTemplate, updateTemplate, deleteTemplate, diff --git a/internal/cmd/commands/credentiallibrariescmd/vault_credentiallibraries.gen.go b/internal/cmd/commands/credentiallibrariescmd/vault_credentiallibraries.gen.go index 84a176816..7fdb932eb 100644 --- a/internal/cmd/commands/credentiallibrariescmd/vault_credentiallibraries.gen.go +++ b/internal/cmd/commands/credentiallibrariescmd/vault_credentiallibraries.gen.go @@ -203,7 +203,7 @@ func (c *VaultCommand) Run(args []string) int { switch c.Func { case "create": - createResult, err = credentiallibrariesClient.Create(c.Context, c.FlagCredentialStoreId, opts...) + createResult, err = credentiallibrariesClient.Create(c.Context, "vault", c.FlagCredentialStoreId, opts...) if exitCode := c.checkFuncError(err); exitCode > 0 { return exitCode } diff --git a/internal/cmd/gencli/input.go b/internal/cmd/gencli/input.go index 00adaddef..20b6b2b61 100644 --- a/internal/cmd/gencli/input.go +++ b/internal/cmd/gencli/input.go @@ -227,18 +227,19 @@ var inputStructs = map[string][]*cmdInfo{ HasId: true, }, { - ResourceType: resource.CredentialLibrary.String(), - Pkg: "credentiallibraries", - StdActions: []string{"create", "update"}, - SubActionPrefix: "vault", - HasExtraCommandVars: true, - SkipNormalHelp: true, - HasExtraHelpFunc: true, - HasId: true, - HasName: true, - HasDescription: true, - Container: "CredentialStore", - VersionedActions: []string{"update"}, + ResourceType: resource.CredentialLibrary.String(), + Pkg: "credentiallibraries", + StdActions: []string{"create", "update"}, + SubActionPrefix: "vault", + HasExtraCommandVars: true, + SkipNormalHelp: true, + HasExtraHelpFunc: true, + HasId: true, + HasName: true, + HasDescription: true, + Container: "CredentialStore", + VersionedActions: []string{"update"}, + NeedsSubtypeInCreate: true, PrefixAttributeFieldErrorsWithSubactionPrefix: true, }, }, diff --git a/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service.go b/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service.go index c8c3d03e1..d85d6f515 100644 --- a/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service.go +++ b/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service.go @@ -2,6 +2,7 @@ package credentiallibraries import ( "context" + "encoding/json" "fmt" "strings" @@ -33,6 +34,11 @@ const ( httpMethodField = "attributes.http_method" httpRequestBodyField = "attributes.http_request_body" credentialMappingPathField = "credential_mapping_overrides" + sshCertUsernameField = "attributes.username" + keyTypeField = "attributes.key_type" + keyBitsField = "attributes.key_bits" + criticalOptionsField = "attributes.critical_options" + extensionsField = "attributes.extensions" domain = "credential" ) @@ -45,7 +51,8 @@ const ( ) var ( - maskManager handlers.MaskManager + maskManager handlers.MaskManager + sshCertMaskManager handlers.MaskManager // IdActions contains the set of actions that can be performed on // individual resources @@ -62,6 +69,18 @@ var ( action.Create, action.List, } + + validCredentialTypesVaultGeneric = []credential.Type{ + credential.UsernamePasswordType, + credential.SshPrivateKeyType, + credential.UnspecifiedType, + } + + validKeyTypes = []string{ + vault.KeyTypeEcdsa, + vault.KeyTypeEd25519, + vault.KeyTypeRsa, + } ) func init() { @@ -70,6 +89,10 @@ func init() { handlers.MaskSource{&pb.CredentialLibrary{}, &pb.VaultCredentialLibraryAttributes{}}); err != nil { panic(err) } + if sshCertMaskManager, err = handlers.NewMaskManager(handlers.MaskDestination{&store.SSHCertificateCredentialLibrary{}}, + handlers.MaskSource{&pb.CredentialLibrary{}, &pb.VaultSSHCertificateCredentialLibraryAttributes{}}); err != nil { + panic(err) + } } // Service handles request as described by the pbs.CredentialLibraryServiceServer interface. @@ -242,11 +265,23 @@ func (s Service) UpdateCredentialLibrary(ctx context.Context, req *pbs.UpdateCre if err != nil { return nil, err } - cur, err := repo.LookupCredentialLibrary(ctx, req.Id) - if err != nil { - return nil, err + var currentCredentialType credential.Type + var mo vault.MappingOverride + switch subtypes.SubtypeFromId(domain, req.GetId()) { + case vault.SSHCertificateLibrarySubtype: + cur, err := repo.LookupSSHCertificateCredentialLibrary(ctx, req.Id) + if err != nil { + return nil, err + } + currentCredentialType = credential.Type(cur.GetCredentialType()) + default: + cur, err := repo.LookupCredentialLibrary(ctx, req.Id) + if err != nil { + return nil, err + } + currentCredentialType = credential.Type(cur.GetCredentialType()) + mo = cur.MappingOverride } - currentCredentialType := credential.Type(cur.GetCredentialType()) if err := validateUpdateRequest(req, currentCredentialType); err != nil { return nil, err @@ -255,7 +290,7 @@ func (s Service) UpdateCredentialLibrary(ctx context.Context, req *pbs.UpdateCre if authResults.Error != nil { return nil, authResults.Error } - cl, err := s.updateInRepo(ctx, authResults.Scope.GetId(), req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem(), currentCredentialType, cur.MappingOverride) + cl, err := s.updateInRepo(ctx, authResults.Scope.GetId(), req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem(), currentCredentialType, mo) if err != nil { return nil, err } @@ -298,16 +333,28 @@ func (s Service) DeleteCredentialLibrary(ctx context.Context, req *pbs.DeleteCre return nil, nil } -func (s Service) listFromRepo(ctx context.Context, storeId string) ([]*vault.CredentialLibrary, error) { +func (s Service) listFromRepo(ctx context.Context, storeId string) ([]credential.Library, error) { const op = "credentiallibraries.(Service).listFromRepo" repo, err := s.repoFn() if err != nil { return nil, errors.Wrap(ctx, err, op) } - csl, err := repo.ListCredentialLibraries(ctx, storeId) + genCsl, err := repo.ListCredentialLibraries(ctx, storeId) if err != nil { return nil, errors.Wrap(ctx, err, op) } + certCsl, err := repo.ListSSHCertificateCredentialLibraries(ctx, storeId) + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + + csl := make([]credential.Library, 0, len(genCsl)+len(certCsl)) + for _, s := range genCsl { + csl = append(csl, s) + } + for _, s := range certCsl { + csl = append(csl, s) + } return csl, nil } @@ -317,32 +364,67 @@ func (s Service) getFromRepo(ctx context.Context, id string) (credential.Library if err != nil { return nil, errors.Wrap(ctx, err, op) } - cs, err := repo.LookupCredentialLibrary(ctx, id) - if err != nil && !errors.IsNotFoundError(err) { - return nil, errors.Wrap(ctx, err, op) + switch subtypes.SubtypeFromId(domain, id) { + case vault.GenericLibrarySubtype: + cs, err := repo.LookupCredentialLibrary(ctx, id) + if err != nil && !errors.IsNotFoundError(err) { + return nil, errors.Wrap(ctx, err, op) + } + if cs == nil { + return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("credential library %q not found", id)) + } + return cs, err + case vault.SSHCertificateLibrarySubtype: + cs, err := repo.LookupSSHCertificateCredentialLibrary(ctx, id) + if err != nil && !errors.IsNotFoundError(err) { + return nil, errors.Wrap(ctx, err, op) + } + if cs == nil { + return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("ssh certificate credential library %q not found", id)) + } + return cs, err } - if cs == nil { - return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("credential library %q not found", id)) - } - return cs, err + return nil, errors.New(ctx, errors.InvalidParameter, op, "unrecognized credential library subtype") } func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.CredentialLibrary) (credential.Library, error) { const op = "credentiallibraries.(Service).createInRepo" - cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item) - if err != nil { - return nil, errors.Wrap(ctx, err, op) - } - repo, err := s.repoFn() - if err != nil { - return nil, errors.Wrap(ctx, err, op) - } - out, err := repo.CreateCredentialLibrary(ctx, scopeId, cl) - if err != nil { - return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create credential library")) - } - if out == nil { - return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create credential library but no error returned from repository.") + var out credential.Library + switch subtypes.SubtypeFromType(domain, item.GetType()) { + case vault.SSHCertificateLibrarySubtype: + cl, err := toStorageVaultSSHCertificateLibrary(item.GetCredentialStoreId(), item) + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + repo, err := s.repoFn() + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + rl, err := repo.CreateSSHCertificateCredentialLibrary(ctx, scopeId, cl) + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create ssh certificate credential library")) + } + if rl == nil { + return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create ssh certificate credential library but no error returned from repository.") + } + out = rl + default: + cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item) + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + repo, err := s.repoFn() + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + rl, err := repo.CreateCredentialLibrary(ctx, scopeId, cl) + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create credential library")) + } + if rl == nil { + return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create credential library but no error returned from repository.") + } + out = rl } return out, nil } @@ -372,26 +454,53 @@ func (s Service) updateInRepo( item.CredentialMappingOverrides = mappingStruct } - cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item) - if err != nil { - return nil, errors.Wrap(ctx, err, op) - } - cl.PublicId = id - - dbMasks = append(dbMasks, maskManager.Translate(masks)...) - if len(dbMasks) == 0 { - return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."}) - } + var out credential.Library + rowsUpdated := 0 repo, err := s.repoFn() if err != nil { return nil, errors.Wrap(ctx, err, op) } - out, rowsUpdated, err := repo.UpdateCredentialLibrary(ctx, projId, cl, item.GetVersion(), dbMasks) - if err != nil { - return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential library")) - } - if rowsUpdated == 0 { - return nil, handlers.NotFoundErrorf("Credential Library %q doesn't exist or incorrect version provided.", id) + switch subtypes.SubtypeFromId(domain, id) { + case vault.SSHCertificateLibrarySubtype: + dbMasks = append(dbMasks, sshCertMaskManager.Translate(masks)...) + if getMapUpdate(criticalOptionsField, masks) { + dbMasks = append(dbMasks, vault.CriticalOptionsField) + } + if getMapUpdate(extensionsField, masks) { + dbMasks = append(dbMasks, vault.ExtensionsField) + } + if len(dbMasks) == 0 { + return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."}) + } + cl, err := toStorageVaultSSHCertificateLibrary(item.GetCredentialStoreId(), item) + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + cl.PublicId = id + out, rowsUpdated, err = repo.UpdateSSHCertificateCredentialLibrary(ctx, projId, cl, item.GetVersion(), dbMasks) + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential library")) + } + if rowsUpdated == 0 { + return nil, handlers.NotFoundErrorf("Credential Library %q doesn't exist or incorrect version provided.", id) + } + default: + dbMasks = append(dbMasks, maskManager.Translate(masks)...) + if len(dbMasks) == 0 { + return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."}) + } + cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item) + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + cl.PublicId = id + out, rowsUpdated, err = repo.UpdateCredentialLibrary(ctx, projId, cl, item.GetVersion(), dbMasks) + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential library")) + } + if rowsUpdated == 0 { + return nil, handlers.NotFoundErrorf("Credential Library %q doesn't exist or incorrect version provided.", id) + } } return out, nil } @@ -402,7 +511,13 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool, if err != nil { return false, err } - rows, err := repo.DeleteCredentialLibrary(ctx, scopeId, id) + rows := 0 + switch subtypes.SubtypeFromId(domain, id) { + case vault.SSHCertificateLibrarySubtype: + rows, err = repo.DeleteSSHCertificateCredentialLibrary(ctx, scopeId, id) + default: + rows, err = repo.DeleteCredentialLibrary(ctx, scopeId, id) + } if err != nil { if errors.IsNotFoundError(err) { return false, nil @@ -428,9 +543,9 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth. parentId = id default: opts = append(opts, auth.WithId(id)) - + parentId = id switch subtypes.SubtypeFromId(domain, id) { - case vault.Subtype: + case vault.GenericLibrarySubtype: cl, err := repo.LookupCredentialLibrary(ctx, id) if err != nil { res.Error = err @@ -441,6 +556,17 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth. return res } parentId = cl.GetStoreId() + case vault.SSHCertificateLibrarySubtype: + cl, err := repo.LookupSSHCertificateCredentialLibrary(ctx, id) + if err != nil { + res.Error = err + return res + } + if cl == nil { + res.Error = handlers.NotFoundError() + return res + } + parentId = cl.GetStoreId() default: res.Error = errors.New(ctx, errors.InvalidParameter, op, "unrecognized credential library subtype from id") return res @@ -515,7 +641,7 @@ func toProto(in credential.Library, opt ...handlers.Option) (*pb.CredentialLibra out.AuthorizedActions = opts.WithAuthorizedActions } switch subtypes.SubtypeFromId(domain, in.GetPublicId()) { - case vault.Subtype: + case vault.GenericLibrarySubtype: vaultIn, ok := in.(*vault.CredentialLibrary) if !ok { return nil, errors.NewDeprecated(errors.Internal, op, "unable to cast to vault credential library") @@ -568,6 +694,47 @@ func toProto(in credential.Library, opt ...handlers.Option) (*pb.CredentialLibra VaultCredentialLibraryAttributes: attrs, } } + case vault.SSHCertificateLibrarySubtype: + vaultIn, ok := in.(*vault.SSHCertificateCredentialLibrary) + if !ok { + return nil, errors.NewDeprecated(errors.Internal, op, "unable to cast to vault ssh certificate credential library") + } + // We don't check for mapping overrides here -- this subtype does not currently support them. + out.CredentialType = vaultIn.GetCredentialType() + if outputFields.Has(globals.AttributesField) { + attrs := &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String(vaultIn.GetVaultPath()), + } + if vaultIn.GetUsername() != "" { + attrs.Username = wrapperspb.String(vaultIn.GetUsername()) + } + if vaultIn.GetKeyType() != "" { + attrs.KeyType = wrapperspb.String(vaultIn.GetKeyType()) + } + if vaultIn.GetKeyBits() != 0 { + attrs.KeyBits = &wrapperspb.UInt32Value{Value: vaultIn.GetKeyBits()} + } + if vaultIn.GetTtl() != "" { + attrs.Ttl = wrapperspb.String(vaultIn.GetTtl()) + } + if vaultIn.GetKeyId() != "" { + attrs.KeyId = wrapperspb.String(vaultIn.GetKeyId()) + } + if vaultIn.GetCriticalOptions() != "" { + co := make(map[string]string) + json.Unmarshal([]byte(vaultIn.GetCriticalOptions()), &co) + attrs.CriticalOptions = co + } + if vaultIn.GetExtensions() != "" { + e := make(map[string]string) + json.Unmarshal([]byte(vaultIn.GetExtensions()), &e) + attrs.Extensions = e + } + out.Attrs = &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: attrs, + } + } + } return &out, nil } @@ -582,7 +749,11 @@ func toStorageVaultLibrary(storeId string, in *pb.CredentialLibrary) (out *vault opts = append(opts, vault.WithDescription(in.GetDescription().GetValue())) } - attrs := in.GetVaultCredentialLibraryAttributes() + attrs := in.GetVaultGenericCredentialLibraryAttributes() + if attrs == nil { + // fallback to attributes for older subtype + attrs = in.GetVaultCredentialLibraryAttributes() + } if attrs.GetHttpMethod() != nil { opts = append(opts, vault.WithMethod(vault.Method(strings.ToUpper(attrs.GetHttpMethod().GetValue())))) } @@ -631,13 +802,66 @@ func toStorageVaultLibrary(storeId string, in *pb.CredentialLibrary) (out *vault return cs, err } +func toStorageVaultSSHCertificateLibrary(storeId string, in *pb.CredentialLibrary) (out *vault.SSHCertificateCredentialLibrary, err error) { + const op = "credentiallibraries.toStorageVaultSSHCertificateLibrary" + var opts []vault.Option + if in.GetName() != nil { + opts = append(opts, vault.WithName(in.GetName().GetValue())) + } + if in.GetDescription() != nil { + opts = append(opts, vault.WithDescription(in.GetDescription().GetValue())) + } + opts = append(opts, vault.WithCredentialType(credential.Type(in.GetCredentialType()))) + + attrs := in.GetVaultSshCertificateCredentialLibraryAttributes() + if attrs.GetKeyType() != nil { + opts = append(opts, vault.WithKeyType(attrs.GetKeyType().GetValue())) + } + if attrs.GetKeyBits() != nil { + opts = append(opts, vault.WithKeyBits(attrs.GetKeyBits().GetValue())) + } + if attrs.GetTtl() != nil { + opts = append(opts, vault.WithTtl(attrs.GetTtl().GetValue())) + } + if attrs.GetKeyId() != nil { + opts = append(opts, vault.WithKeyId(attrs.GetKeyId().GetValue())) + } + if attrs.GetCriticalOptions() != nil { + co, err := json.Marshal(attrs.GetCriticalOptions()) + if err != nil { + return nil, err + } + opts = append(opts, vault.WithCriticalOptions(string(co))) + } + if attrs.GetExtensions() != nil { + e, err := json.Marshal(attrs.GetExtensions()) + if err != nil { + return nil, err + } + opts = append(opts, vault.WithExtensions(string(e))) + } + + cs, err := vault.NewSSHCertificateCredentialLibrary(storeId, attrs.GetPath().GetValue(), attrs.GetUsername().GetValue(), opts...) + if err != nil { + return nil, errors.WrapDeprecated(err, op, errors.WithMsg("unable to build credential library")) + } + return cs, err +} + // A validateX method should exist for each method above. These methods do not make calls to any backing service but enforce // requirements on the structure of the request. They verify that: // - The path passed in is correctly formatted // - All required parameters are set // - There are no conflicting parameters provided func validateGetRequest(req *pbs.GetCredentialLibraryRequest) error { - return handlers.ValidateGetRequest(handlers.NoopValidatorFn, req, vault.CredentialLibraryPrefix) + prefix := "" + switch subtypes.SubtypeFromId(domain, req.GetId()) { + case vault.SSHCertificateLibrarySubtype: + prefix = vault.SSHCertificateCredentialLibraryPrefix + default: + prefix = vault.CredentialLibraryPrefix + } + return handlers.ValidateGetRequest(handlers.NoopValidatorFn, req, prefix) } func validateCreateRequest(req *pbs.CreateCredentialLibraryRequest) error { @@ -645,23 +869,82 @@ func validateCreateRequest(req *pbs.CreateCredentialLibraryRequest) error { badFields := map[string]string{} switch subtypes.SubtypeFromId(domain, req.GetItem().GetCredentialStoreId()) { case vault.Subtype: - if t := req.GetItem().GetType(); t != "" && subtypes.SubtypeFromType(domain, t) != vault.Subtype { + t := req.GetItem().GetType() + if t == "" { + badFields[globals.TypeField] = "This is a required field." + } + + // support older vault generic libraries with 'vault.Subtype'. + if subtypes.SubtypeFromType(domain, t) == vault.Subtype { + req.GetItem().Type = vault.GenericLibrarySubtype.String() + t = vault.GenericLibrarySubtype.String() + } + + if subtypes.SubtypeFromType(domain, t) != vault.GenericLibrarySubtype && + subtypes.SubtypeFromType(domain, t) != vault.SSHCertificateLibrarySubtype { badFields[globals.CredentialStoreIdField] = "If included, type must match that of the credential store." } - attrs := req.GetItem().GetVaultCredentialLibraryAttributes() - if attrs == nil { - badFields[attributesPathField] = "This is a required field." + + switch subtypes.SubtypeFromType(domain, req.GetItem().GetType()) { + case vault.GenericLibrarySubtype: + isValidCred := false + ct := req.GetItem().GetCredentialType() + for _, t := range validCredentialTypesVaultGeneric { + if ct == "" || ct == string(t) { + isValidCred = true + break + } + } + if !isValidCred { + badFields[globals.CredentialTypeField] = fmt.Sprintf("Unknown credential type %q", ct) + } + + attrs := req.GetItem().GetVaultGenericCredentialLibraryAttributes() + if attrs == nil { + // fallback to attributes for older subtype + attrs = req.GetItem().GetVaultCredentialLibraryAttributes() + if attrs == nil { + badFields[attributesPathField] = "This is a required field." + } + } + if attrs.GetPath().GetValue() == "" { + badFields[vaultPathField] = "This is a required field." + } + if m := attrs.GetHttpMethod(); m != nil && !strutil.StrListContains([]string{"GET", "POST"}, strings.ToUpper(m.GetValue())) { + badFields[httpMethodField] = "If set, value must be 'GET' or 'POST'." + } + if b := attrs.GetHttpRequestBody(); b != nil && strings.ToUpper(attrs.GetHttpMethod().GetValue()) != "POST" { + badFields[httpRequestBodyField] = fmt.Sprintf("Field can only be set if %q is set to the value 'POST'.", httpMethodField) + } + validateMapping(badFields, credential.Type(req.GetItem().GetCredentialType()), req.GetItem().CredentialMappingOverrides.AsMap()) + case vault.SSHCertificateLibrarySubtype: + if req.GetItem().GetCredentialType() != "" { + badFields[globals.CredentialTypeField] = fmt.Sprintf("This field is read only and cannot be set.") + } + + attrs := req.GetItem().GetVaultSshCertificateCredentialLibraryAttributes() + if attrs == nil { + badFields[attributesPathField] = "This is a required field." + } + if attrs.GetPath().GetValue() == "" { + badFields[vaultPathField] = "This is a required field." + } + if attrs.GetUsername().GetValue() == "" { + badFields[sshCertUsernameField] = "This is a required field." + } + if (attrs.GetKeyType() == nil) != (attrs.GetKeyBits() == nil) { + if attrs.GetKeyType() != nil && attrs.GetKeyType().GetValue() != vault.KeyTypeEd25519 { + badFields[keyTypeField] = fmt.Sprintf("If set, %q must also be set.", keyBitsField) + } + if attrs.GetKeyBits() != nil { + badFields[keyBitsField] = fmt.Sprintf("If set, %q must also be set.", keyTypeField) + } + } + if t := attrs.GetKeyType(); t != nil && !strutil.StrListContains(validKeyTypes, strings.ToLower(t.GetValue())) { + badFields[keyTypeField] = "If set, value must be 'ed25519', 'ecdsa', or 'rsa'." + } + validateKeyBits(badFields, attrs.GetKeyBits().GetValue(), attrs.GetKeyType().GetValue()) } - if attrs.GetPath().GetValue() == "" { - badFields[vaultPathField] = "This is a required field." - } - if m := attrs.GetHttpMethod(); m != nil && !strutil.StrListContains([]string{"GET", "POST"}, strings.ToUpper(m.GetValue())) { - badFields[httpMethodField] = "If set, value must be 'GET' or 'POST'." - } - if b := attrs.GetHttpRequestBody(); b != nil && strings.ToUpper(attrs.GetHttpMethod().GetValue()) != "POST" { - badFields[httpRequestBodyField] = fmt.Sprintf("Field can only be set if %q is set to the value 'POST'.", httpMethodField) - } - validateMapping(badFields, credential.Type(req.GetItem().GetCredentialType()), req.GetItem().CredentialMappingOverrides.AsMap()) default: badFields[globals.CredentialStoreIdField] = "This field must be a valid credential store id." } @@ -670,17 +953,29 @@ func validateCreateRequest(req *pbs.CreateCredentialLibraryRequest) error { } func validateUpdateRequest(req *pbs.UpdateCredentialLibraryRequest, currentCredentialType credential.Type) error { + prefix := "" + st := subtypes.SubtypeFromId(domain, req.GetId()) + switch st { + case vault.GenericLibrarySubtype: + prefix = vault.CredentialLibraryPrefix + case vault.SSHCertificateLibrarySubtype: + prefix = vault.SSHCertificateCredentialLibraryPrefix + } return handlers.ValidateUpdateRequest(req, req.GetItem(), func() map[string]string { badFields := map[string]string{} - switch subtypes.SubtypeFromId(domain, req.GetId()) { - case vault.Subtype: - if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != vault.Subtype { + switch st { + case vault.GenericLibrarySubtype: + if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != vault.GenericLibrarySubtype { badFields[globals.TypeField] = "Cannot modify resource type." } if req.GetItem().GetCredentialType() != "" && req.GetItem().GetCredentialType() != string(currentCredentialType) { badFields[globals.CredentialTypeField] = "Cannot modify credential type." } - attrs := req.GetItem().GetVaultCredentialLibraryAttributes() + attrs := req.GetItem().GetVaultGenericCredentialLibraryAttributes() + if attrs == nil { + // fallback to attributes for older subtype + attrs = req.GetItem().GetVaultCredentialLibraryAttributes() + } if attrs != nil { if handlers.MaskContains(req.GetUpdateMask().GetPaths(), vaultPathField) && attrs.GetPath().GetValue() == "" { badFields[vaultPathField] = "This is a required field and cannot be set to empty." @@ -693,13 +988,33 @@ func validateUpdateRequest(req *pbs.UpdateCredentialLibraryRequest, currentCrede } validateMapping(badFields, currentCredentialType, req.GetItem().CredentialMappingOverrides.AsMap()) } + case vault.SSHCertificateLibrarySubtype: + if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != vault.SSHCertificateLibrarySubtype { + badFields[globals.TypeField] = "Cannot modify resource type." + } + if req.GetItem().GetCredentialType() != "" && req.GetItem().GetCredentialType() != string(currentCredentialType) { + badFields[globals.CredentialTypeField] = "Cannot modify credential type." + } + attrs := req.GetItem().GetVaultSshCertificateCredentialLibraryAttributes() + if attrs != nil { + if handlers.MaskContains(req.GetUpdateMask().GetPaths(), vaultPathField) && attrs.GetPath().GetValue() == "" { + badFields[vaultPathField] = "This is a required field and cannot be set to empty." + } + if u := attrs.GetUsername().GetValue(); handlers.MaskContains(req.GetUpdateMask().GetPaths(), sshCertUsernameField) && u == "" { + badFields[sshCertUsernameField] = "This is a required field and cannot be set to empty." + } + if t := attrs.GetKeyType(); t != nil && !strutil.StrListContains(validKeyTypes, strings.ToLower(t.GetValue())) { + badFields[keyTypeField] = "If set, value must be 'ed25519', 'ecdsa', or 'rsa'." + } + validateKeyBits(badFields, attrs.GetKeyBits().GetValue(), attrs.GetKeyType().GetValue()) + } } return badFields - }, vault.CredentialLibraryPrefix) + }, prefix) } func validateDeleteRequest(req *pbs.DeleteCredentialLibraryRequest) error { - return handlers.ValidateDeleteRequest(handlers.NoopValidatorFn, req, vault.CredentialLibraryPrefix) + return handlers.ValidateDeleteRequest(handlers.NoopValidatorFn, req, vault.CredentialLibraryPrefix, vault.SSHCertificateCredentialLibraryPrefix) } func validateListRequest(req *pbs.ListCredentialLibrariesRequest) error { @@ -747,6 +1062,38 @@ func validateMapping(badFields map[string]string, credentialType credential.Type } } +// validateKeyBits appends to badFields if keyBits and keyType aren't accepted combinations for an SSHCertificateCredentialLibrary. +// If keyType is an empty string, validateKeyBits only validates keyBits. +func validateKeyBits(badFields map[string]string, keyBits uint32, keyType string) { + switch keyBits { + case vault.KeyBitsDefault: + case vault.KeyBitsEcdsa256, vault.KeyBitsEcdsa384, vault.KeyBitsEcdsa521: + if keyType != "" && keyType != vault.KeyTypeEcdsa { + badFields[keyBitsField] = fmt.Sprintf("Invalid bit size %d for key type %s", keyBits, keyType) + } + case vault.KeyBitsRsa2048, vault.KeyBitsRsa3072, vault.KeyBitsRsa4096: + if keyType != "" && keyType != vault.KeyTypeRsa { + badFields[keyBitsField] = fmt.Sprintf("Invalid bit size %d for key type %s", keyBits, keyType) + } + default: + badFields[keyBitsField] = fmt.Sprintf("Invalid bit size %d", keyBits) + } +} + +func getMapUpdate(field string, apiMasks []string) bool { + for _, m := range apiMasks { + if m == field { + return true + } + + fieldPrefix := fmt.Sprintf("%v.", field) + if s := strings.SplitN(m, fieldPrefix, 2); len(s) == 2 { + return true + } + } + return false +} + func getMappingUpdates(credentialType credential.Type, current vault.MappingOverride, new map[string]any, apiMasks []string) (map[string]any, bool) { ret := make(map[string]any) masks := make(map[string]bool) diff --git a/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service_test.go b/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service_test.go index 37c05350c..e1192e981 100644 --- a/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service_test.go +++ b/internal/daemon/controller/handlers/credentiallibraries/credentiallibrary_service_test.go @@ -2,6 +2,7 @@ package credentiallibraries import ( "context" + "encoding/json" "fmt" "sort" "strings" @@ -65,7 +66,7 @@ func TestList(t *testing.T) { CreatedTime: l.GetCreateTime().GetTimestamp(), UpdatedTime: l.GetUpdateTime().GetTimestamp(), Version: l.GetVersion(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), AuthorizedActions: testAuthorizedActions, Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ @@ -75,7 +76,26 @@ func TestList(t *testing.T) { }, }) } - + for _, l := range vault.TestSSHCertificateCredentialLibraries(t, conn, wrapper, store.GetPublicId(), 10) { + wantLibraries = append(wantLibraries, &pb.CredentialLibrary{ + Id: l.GetPublicId(), + CredentialStoreId: l.GetStoreId(), + CredentialType: l.GetCredentialType(), + Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()}, + CreatedTime: l.GetCreateTime().GetTimestamp(), + UpdatedTime: l.GetUpdateTime().GetTimestamp(), + Version: l.GetVersion(), + Type: vault.SSHCertificateLibrarySubtype.String(), + AuthorizedActions: testAuthorizedActions, + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyType: wrapperspb.String(l.GetKeyType()), + Path: wrapperspb.String(l.GetVaultPath()), + Username: wrapperspb.String(l.GetUsername()), + }, + }, + }) + } cases := []struct { name string req *pbs.ListCredentialLibrariesRequest @@ -101,12 +121,6 @@ func TestList(t *testing.T) { res: &pbs.ListCredentialLibrariesResponse{Items: wantLibraries[1:2]}, anonRes: &pbs.ListCredentialLibrariesResponse{Items: wantLibraries[1:2]}, }, - { - name: "Filter on Attribute", - req: &pbs.ListCredentialLibrariesRequest{CredentialStoreId: store.GetPublicId(), Filter: fmt.Sprintf(`"/item/attributes/path"==%q`, wantLibraries[2].GetVaultCredentialLibraryAttributes().GetPath().Value)}, - res: &pbs.ListCredentialLibrariesResponse{Items: wantLibraries[2:3]}, - anonRes: &pbs.ListCredentialLibrariesResponse{}, // anonymous user does not have access to attributes - }, { name: "Filter to No Libraries", req: &pbs.ListCredentialLibrariesRequest{CredentialStoreId: store.GetPublicId(), Filter: `"/item/id"=="doesnt match"`}, @@ -154,6 +168,119 @@ func TestList(t *testing.T) { } } +func TestList_Attributes(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + wrapper := db.TestWrapper(t) + kms := kms.TestKms(t, conn, wrapper) + sche := scheduler.TestScheduler(t, conn, wrapper) + rw := db.New(conn) + + iamRepo := iam.TestRepo(t, conn, wrapper) + iamRepoFn := func() (*iam.Repository, error) { + return iamRepo, nil + } + repoFn := func() (*vault.Repository, error) { + return vault.NewRepository(rw, rw, kms, sche) + } + _, prj := iam.TestScopes(t, iamRepo) + + ts := vault.TestCredentialStores(t, conn, wrapper, prj.GetPublicId(), 2) + storeGeneric, storeSSHCertificate := ts[0], ts[1] + var wantLibrariesGeneric []*pb.CredentialLibrary + var wantLibrariesSSHCertificate []*pb.CredentialLibrary + for _, l := range vault.TestCredentialLibraries(t, conn, wrapper, storeGeneric.GetPublicId(), 5) { + wantLibrariesGeneric = append(wantLibrariesGeneric, &pb.CredentialLibrary{ + Id: l.GetPublicId(), + CredentialStoreId: l.GetStoreId(), + Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()}, + CreatedTime: l.GetCreateTime().GetTimestamp(), + UpdatedTime: l.GetUpdateTime().GetTimestamp(), + Version: l.GetVersion(), + Type: vault.GenericLibrarySubtype.String(), + AuthorizedActions: testAuthorizedActions, + Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ + VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ + Path: wrapperspb.String(l.GetVaultPath()), + HttpMethod: wrapperspb.String(l.GetHttpMethod()), + }, + }, + }) + } + for _, l := range vault.TestSSHCertificateCredentialLibraries(t, conn, wrapper, storeSSHCertificate.GetPublicId(), 10) { + wantLibrariesSSHCertificate = append(wantLibrariesSSHCertificate, &pb.CredentialLibrary{ + Id: l.GetPublicId(), + CredentialStoreId: l.GetStoreId(), + CredentialType: l.GetCredentialType(), + Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()}, + CreatedTime: l.GetCreateTime().GetTimestamp(), + UpdatedTime: l.GetUpdateTime().GetTimestamp(), + Version: l.GetVersion(), + Type: vault.SSHCertificateLibrarySubtype.String(), + AuthorizedActions: testAuthorizedActions, + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyType: wrapperspb.String(l.GetKeyType()), + Path: wrapperspb.String(l.GetVaultPath()), + Username: wrapperspb.String(l.GetUsername()), + }, + }, + }) + } + cases := []struct { + name string + req *pbs.ListCredentialLibrariesRequest + res *pbs.ListCredentialLibrariesResponse + anonRes *pbs.ListCredentialLibrariesResponse + err error + }{ + { + name: "Filter on Attribute Generic Library", + req: &pbs.ListCredentialLibrariesRequest{CredentialStoreId: storeGeneric.GetPublicId(), Filter: fmt.Sprintf(`"/item/attributes/path"==%q`, wantLibrariesGeneric[2].GetVaultCredentialLibraryAttributes().GetPath().Value)}, + res: &pbs.ListCredentialLibrariesResponse{Items: wantLibrariesGeneric[2:3]}, + anonRes: &pbs.ListCredentialLibrariesResponse{}, // anonymous user does not have access to attributes + }, + { + name: "Filter on Attribute SSH Certificate Library", + req: &pbs.ListCredentialLibrariesRequest{CredentialStoreId: storeSSHCertificate.GetPublicId(), Filter: fmt.Sprintf(`"/item/attributes/path"==%q`, wantLibrariesSSHCertificate[2].GetVaultSshCertificateCredentialLibraryAttributes().GetPath().Value)}, + res: &pbs.ListCredentialLibrariesResponse{Items: wantLibrariesSSHCertificate[2:3]}, + anonRes: &pbs.ListCredentialLibrariesResponse{}, // anonymous user does not have access to attributes + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + s, err := NewService(repoFn, iamRepoFn) + require.NoError(t, err, "Couldn't create new host set service.") + + // Test non-anonymous listing + got, gErr := s.ListCredentialLibraries(auth.DisabledAuthTestContext(iamRepoFn, prj.GetPublicId()), tc.req) + if tc.err != nil { + require.Error(t, gErr) + assert.True(t, errors.Is(gErr, tc.err), "ListCredentialLibrary(%q) got error %v, wanted %v", tc.req, gErr, tc.err) + return + } + require.NoError(t, gErr) + sort.Slice(got.Items, func(i, j int) bool { + return got.Items[i].GetId() < got.Items[j].GetId() + }) + want := proto.Clone(tc.res).(*pbs.ListCredentialLibrariesResponse) + sort.Slice(want.Items, func(i, j int) bool { + return want.Items[i].GetId() < want.Items[j].GetId() + }) + assert.Empty(t, cmp.Diff(got, want, protocmp.Transform())) + + // Test anonymous listing + got, gErr = s.ListCredentialLibraries(auth.DisabledAuthTestContext(iamRepoFn, prj.GetPublicId(), auth.WithUserId(globals.AnonymousUserId)), tc.req) + require.NoError(t, gErr) + assert.Len(t, got.Items, len(tc.anonRes.Items)) + for _, item := range got.GetItems() { + require.Nil(t, item.CreatedTime) + require.Nil(t, item.UpdatedTime) + require.Zero(t, item.Version) + } + }) + } +} + func TestCreate(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) @@ -186,6 +313,7 @@ func TestCreate(t *testing.T) { name: "missing vault path", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{}, }, @@ -197,6 +325,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Id", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Id: vault.CredentialLibraryPrefix + "_notallowed", Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ @@ -211,6 +340,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Created Time", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), CreatedTime: timestamppb.Now(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ @@ -225,6 +355,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Update Time", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), UpdatedTime: timestamppb.Now(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ @@ -252,7 +383,7 @@ func TestCreate(t *testing.T) { { name: "parent id must be included", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -266,6 +397,7 @@ func TestCreate(t *testing.T) { name: "Cannot specify a http request body when http method is get", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -280,6 +412,7 @@ func TestCreate(t *testing.T) { name: "Invalid Method", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -294,6 +427,7 @@ func TestCreate(t *testing.T) { name: "Request Body With GET Method", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -308,6 +442,7 @@ func TestCreate(t *testing.T) { name: "Invalid credential type", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -322,6 +457,7 @@ func TestCreate(t *testing.T) { name: "Invalid username_password mapping", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -345,6 +481,7 @@ func TestCreate(t *testing.T) { name: "Using POST method", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -363,7 +500,7 @@ func TestCreate(t *testing.T) { UpdatedTime: store.GetUpdateTime().GetTimestamp(), Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, Version: 1, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -379,6 +516,7 @@ func TestCreate(t *testing.T) { name: "Create a valid vault CredentialLibrary", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ @@ -399,7 +537,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, Version: 1, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -414,6 +552,7 @@ func TestCreate(t *testing.T) { name: "Create a valid vault CredentialLibrary username_password type", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -431,7 +570,7 @@ func TestCreate(t *testing.T) { UpdatedTime: store.GetUpdateTime().GetTimestamp(), Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, Version: 1, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -447,6 +586,7 @@ func TestCreate(t *testing.T) { name: "Create a valid vault CredentialLibrary username_password type with username mapping", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -472,7 +612,7 @@ func TestCreate(t *testing.T) { UpdatedTime: store.GetUpdateTime().GetTimestamp(), Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, Version: 1, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -496,6 +636,7 @@ func TestCreate(t *testing.T) { name: "Create a valid vault CredentialLibrary username_password type with username/password mapping", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -522,7 +663,7 @@ func TestCreate(t *testing.T) { UpdatedTime: store.GetUpdateTime().GetTimestamp(), Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, Version: 1, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -547,6 +688,7 @@ func TestCreate(t *testing.T) { name: "Create a valid vault CredentialLibrary ssh_private_key type", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -564,7 +706,7 @@ func TestCreate(t *testing.T) { UpdatedTime: store.GetUpdateTime().GetTimestamp(), Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, Version: 1, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -580,6 +722,7 @@ func TestCreate(t *testing.T) { name: "Create a valid vault CredentialLibrary ssh_private_key type with mapping", req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -607,7 +750,7 @@ func TestCreate(t *testing.T) { UpdatedTime: store.GetUpdateTime().GetTimestamp(), Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, Version: 1, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("something"), @@ -629,6 +772,38 @@ func TestCreate(t *testing.T) { }, }, }, + { + name: "Create a valid vault CredentialLibrary with the 'vault' subtype", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.Subtype.String(), + Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ + VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + }, + }, + }}, + idPrefix: vault.CredentialLibraryPrefix + "_", + res: &pbs.CreateCredentialLibraryResponse{ + Uri: fmt.Sprintf("credential-libraries/%s_", vault.CredentialLibraryPrefix), + Item: &pb.CredentialLibrary{ + Id: store.GetPublicId(), + CredentialStoreId: store.GetPublicId(), + CreatedTime: store.GetCreateTime().GetTimestamp(), + UpdatedTime: store.GetUpdateTime().GetTimestamp(), + Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, + Version: 1, + Type: vault.GenericLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultCredentialLibraryAttributes{ + VaultCredentialLibraryAttributes: &pb.VaultCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + HttpMethod: wrapperspb.String("GET"), + }, + }, + AuthorizedActions: testAuthorizedActions, + }, + }, + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { @@ -717,6 +892,11 @@ func TestGet(t *testing.T) { sshPkLib, err := repo.CreateCredentialLibrary(context.Background(), prj.GetPublicId(), lib1) require.NoError(t, err) + lib2, err := vault.NewSSHCertificateCredentialLibrary(store.GetPublicId(), "/ssh/sign/foo", "username") + require.NoError(t, err) + sshCertLib, err := repo.CreateSSHCertificateCredentialLibrary(context.Background(), prj.GetPublicId(), lib2) + require.NoError(t, err) + cases := []struct { name string id string @@ -731,7 +911,7 @@ func TestGet(t *testing.T) { Id: unspecifiedLib.GetPublicId(), CredentialStoreId: unspecifiedLib.GetStoreId(), Scope: &scopepb.ScopeInfo{Id: store.GetProjectId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()}, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), AuthorizedActions: testAuthorizedActions, CreatedTime: unspecifiedLib.CreateTime.GetTimestamp(), UpdatedTime: unspecifiedLib.UpdateTime.GetTimestamp(), @@ -753,7 +933,7 @@ func TestGet(t *testing.T) { Id: userPassLib.GetPublicId(), CredentialStoreId: userPassLib.GetStoreId(), Scope: &scopepb.ScopeInfo{Id: store.GetProjectId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()}, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), AuthorizedActions: testAuthorizedActions, CreatedTime: userPassLib.CreateTime.GetTimestamp(), UpdatedTime: userPassLib.UpdateTime.GetTimestamp(), @@ -785,7 +965,7 @@ func TestGet(t *testing.T) { Id: sshPkLib.GetPublicId(), CredentialStoreId: sshPkLib.GetStoreId(), Scope: &scopepb.ScopeInfo{Id: store.GetProjectId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()}, - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), AuthorizedActions: testAuthorizedActions, CreatedTime: sshPkLib.CreateTime.GetTimestamp(), UpdatedTime: sshPkLib.UpdateTime.GetTimestamp(), @@ -810,6 +990,30 @@ func TestGet(t *testing.T) { }, }, }, + { + name: "success-ssh-certificate", + id: sshCertLib.GetPublicId(), + res: &pbs.GetCredentialLibraryResponse{ + Item: &pb.CredentialLibrary{ + Id: sshCertLib.GetPublicId(), + CredentialStoreId: sshCertLib.GetStoreId(), + CredentialType: sshCertLib.GetCredentialType(), + Scope: &scopepb.ScopeInfo{Id: store.GetProjectId(), Type: scope.Project.String(), ParentScopeId: prj.GetParentId()}, + Type: vault.SSHCertificateLibrarySubtype.String(), + AuthorizedActions: testAuthorizedActions, + CreatedTime: sshCertLib.CreateTime.GetTimestamp(), + UpdatedTime: sshCertLib.UpdateTime.GetTimestamp(), + Version: 1, + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyType: wrapperspb.String(sshCertLib.GetKeyType()), + Path: wrapperspb.String(sshCertLib.GetVaultPath()), + Username: wrapperspb.String(sshCertLib.GetUsername()), + }, + }, + }, + }, + }, { name: "not found error", id: fmt.Sprintf("%s_1234567890", vault.CredentialLibraryPrefix), @@ -863,6 +1067,7 @@ func TestDelete(t *testing.T) { store := vault.TestCredentialStores(t, conn, wrapper, prj.GetPublicId(), 1)[0] vl := vault.TestCredentialLibraries(t, conn, wrapper, store.GetPublicId(), 1)[0] + vl2 := vault.TestSSHCertificateCredentialLibraries(t, conn, wrapper, store.GetPublicId(), 1)[0] s, err := NewService(repoFn, iamRepoFn) require.NoError(t, err) @@ -876,6 +1081,10 @@ func TestDelete(t *testing.T) { name: "success", id: vl.GetPublicId(), }, + { + name: "success-ssh-cert", + id: vl2.GetPublicId(), + }, { name: "not found error", id: fmt.Sprintf("%s_1234567890", vault.CredentialLibraryPrefix), @@ -1673,3 +1882,668 @@ func TestUpdate(t *testing.T) { assert.Nil(t, cl.GetItem().GetVaultCredentialLibraryAttributes().GetHttpRequestBody()) }) } + +func TestCreate_SSHCertificateCredentialLibrary(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + wrapper := db.TestWrapper(t) + kms := kms.TestKms(t, conn, wrapper) + sche := scheduler.TestScheduler(t, conn, wrapper) + rw := db.New(conn) + + iamRepo := iam.TestRepo(t, conn, wrapper) + iamRepoFn := func() (*iam.Repository, error) { + return iamRepo, nil + } + repoFn := func() (*vault.Repository, error) { + return vault.NewRepository(rw, rw, kms, sche) + } + + _, prj := iam.TestScopes(t, iamRepo) + store := vault.TestCredentialStores(t, conn, wrapper, prj.GetPublicId(), 1)[0] + defaultCL := vault.TestSSHCertificateCredentialLibraries(t, conn, wrapper, store.GetPublicId(), 1)[0] + defaultCreated := defaultCL.GetCreateTime().GetTimestamp() + + cases := []struct { + name string + req *pbs.CreateCredentialLibraryRequest + res *pbs.CreateCredentialLibraryResponse + idPrefix string + err error + wantErr bool + }{ + { + name: "missing vault path", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Username: wrapperspb.String("username"), + }, + }, + }}, + idPrefix: vault.SSHCertificateCredentialLibraryPrefix + "_", + wantErr: true, + }, + { + name: "missing username", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + }, + }, + }}, + idPrefix: vault.SSHCertificateCredentialLibraryPrefix + "_", + wantErr: true, + }, + { + name: "Can't specify Id", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + Id: vault.SSHCertificateCredentialLibraryPrefix + "_notallowed", + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + Username: wrapperspb.String("username"), + }, + }, + }}, + res: nil, + err: handlers.ApiErrorWithCode(codes.InvalidArgument), + }, + { + name: "Can't specify Created Time", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + CreatedTime: timestamppb.Now(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + Username: wrapperspb.String("username"), + }, + }, + }}, + res: nil, + err: handlers.ApiErrorWithCode(codes.InvalidArgument), + }, + { + name: "Can't specify Update Time", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + UpdatedTime: timestamppb.Now(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + Username: wrapperspb.String("username"), + }, + }, + }}, + res: nil, + err: handlers.ApiErrorWithCode(codes.InvalidArgument), + }, + { + name: "Type and parent id must match", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: "static", + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + Username: wrapperspb.String("username"), + }, + }, + }}, + res: nil, + err: handlers.ApiErrorWithCode(codes.InvalidArgument), + }, + { + name: "parent id must be included", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + Username: wrapperspb.String("username"), + }, + }, + }}, + res: nil, + err: handlers.ApiErrorWithCode(codes.InvalidArgument), + }, + { + name: "Invalid credential type", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + Username: wrapperspb.String("username"), + }, + }, + CredentialType: "fake-type", + }}, + res: nil, + err: handlers.ApiErrorWithCode(codes.InvalidArgument), + }, + { + name: "Invalid key type key bits combination", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("something"), + Username: wrapperspb.String("username"), + KeyType: wrapperspb.String(vault.KeyTypeEd25519), + KeyBits: wrapperspb.UInt32(256), + }, + }, + }}, + res: nil, + err: handlers.ApiErrorWithCode(codes.InvalidArgument), + }, + { + name: "Create a valid vault SSHCertificateCredentialLibrary", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + Name: &wrapperspb.StringValue{Value: "name"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("/ssh/sign/foo"), + Username: wrapperspb.String("username"), + }, + }, + }}, + idPrefix: vault.SSHCertificateCredentialLibraryPrefix + "_", + res: &pbs.CreateCredentialLibraryResponse{ + Uri: fmt.Sprintf("credential-libraries/%s_", vault.SSHCertificateCredentialLibraryPrefix), + Item: &pb.CredentialLibrary{ + Id: store.GetPublicId(), + CredentialStoreId: store.GetPublicId(), + CreatedTime: store.GetCreateTime().GetTimestamp(), + UpdatedTime: store.GetUpdateTime().GetTimestamp(), + Name: &wrapperspb.StringValue{Value: "name"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, + Version: 1, + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("/ssh/sign/foo"), + Username: wrapperspb.String("username"), + KeyType: wrapperspb.String(vault.KeyTypeEd25519), + }, + }, + AuthorizedActions: testAuthorizedActions, + CredentialType: string(credential.SshCertificateType), + }, + }, + }, + { + name: "Seting key type ed25119 with key bits nil", + req: &pbs.CreateCredentialLibraryRequest{Item: &pb.CredentialLibrary{ + CredentialStoreId: store.GetPublicId(), + Type: vault.SSHCertificateLibrarySubtype.String(), + Name: &wrapperspb.StringValue{Value: "name2"}, + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("/ssh/sign/foo"), + Username: wrapperspb.String("username"), + KeyType: wrapperspb.String(vault.KeyTypeEd25519), + }, + }, + }}, + idPrefix: vault.SSHCertificateCredentialLibraryPrefix + "_", + res: &pbs.CreateCredentialLibraryResponse{ + Uri: fmt.Sprintf("credential-libraries/%s_", vault.SSHCertificateCredentialLibraryPrefix), + Item: &pb.CredentialLibrary{ + Id: store.GetPublicId(), + CredentialStoreId: store.GetPublicId(), + CreatedTime: store.GetCreateTime().GetTimestamp(), + UpdatedTime: store.GetUpdateTime().GetTimestamp(), + Name: &wrapperspb.StringValue{Value: "name2"}, + Scope: &scopepb.ScopeInfo{Id: prj.GetPublicId(), Type: prj.GetType(), ParentScopeId: prj.GetParentId()}, + Version: 1, + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("/ssh/sign/foo"), + Username: wrapperspb.String("username"), + KeyType: wrapperspb.String(vault.KeyTypeEd25519), + }, + }, + AuthorizedActions: testAuthorizedActions, + CredentialType: string(credential.SshCertificateType), + }, + }, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + s, err := NewService(repoFn, iamRepoFn) + require.NoError(err, "Error when getting new credential store service.") + + got, gErr := s.CreateCredentialLibrary(auth.DisabledAuthTestContext(iamRepoFn, prj.GetPublicId()), tc.req) + if tc.wantErr || tc.err != nil { + require.Error(gErr) + if tc.err != nil { + assert.True(errors.Is(gErr, tc.err), "CreateCredentialLibrary(...) got error %v, wanted %v", gErr, tc.err) + } + return + } + require.NoError(gErr) + if tc.res == nil { + require.Nil(got) + } + if got != nil { + assert.Contains(got.GetUri(), tc.res.Uri) + assert.True(strings.HasPrefix(got.GetItem().GetId(), tc.idPrefix)) + gotCreateTime := got.GetItem().GetCreatedTime() + gotUpdateTime := got.GetItem().GetUpdatedTime() + + // Verify it is a credential store created after the test setup's default credential store + assert.True(gotCreateTime.AsTime().After(defaultCreated.AsTime()), "New credential store should have been created after default credential store. Was created %v, which is after %v", gotCreateTime, defaultCreated) + assert.True(gotUpdateTime.AsTime().After(defaultCreated.AsTime()), "New credential store should have been updated after default credential store. Was updated %v, which is after %v", gotUpdateTime, defaultCreated) + + // Clear all values which are hard to compare against. + got.Uri, tc.res.Uri = "", "" + got.Item.Id, tc.res.Item.Id = "", "" + got.Item.CreatedTime, got.Item.UpdatedTime, tc.res.Item.CreatedTime, tc.res.Item.UpdatedTime = nil, nil, nil, nil + } + assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform(), protocmp.SortRepeatedFields(got)), "CreateCredentialLibrary(%q) got response %q, wanted %q", tc.req, got, tc.res) + }) + } +} + +func TestUpdate_SSHCertificateCredentialLibrary(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + wrapper := db.TestWrapper(t) + kms := kms.TestKms(t, conn, wrapper) + sche := scheduler.TestScheduler(t, conn, wrapper) + rw := db.New(conn) + + iamRepo := iam.TestRepo(t, conn, wrapper) + iamRepoFn := func() (*iam.Repository, error) { + return iamRepo, nil + } + repoFn := func() (*vault.Repository, error) { + return vault.NewRepository(rw, rw, kms, sche) + } + + _, prj := iam.TestScopes(t, iamRepo) + ctx := auth.DisabledAuthTestContext(iamRepoFn, prj.GetPublicId()) + + s, err := NewService(repoFn, iamRepoFn) + require.NoError(t, err) + cs := vault.TestCredentialStores(t, conn, wrapper, prj.GetPublicId(), 2) + store, diffStore := cs[0], cs[1] + + freshLibrary := func(opt ...vault.Option) (*vault.SSHCertificateCredentialLibrary, func()) { + repo, err := repoFn() + require.NoError(t, err) + lib, err := vault.NewSSHCertificateCredentialLibrary(store.GetPublicId(), "/ssh/sign/foo", "username", opt...) + require.NoError(t, err) + + vl, err := repo.CreateSSHCertificateCredentialLibrary(ctx, prj.GetPublicId(), lib) + require.NoError(t, err) + clean := func() { + _, err := s.DeleteCredentialLibrary(ctx, &pbs.DeleteCredentialLibraryRequest{Id: vl.GetPublicId()}) + require.NoError(t, err) + } + return vl, clean + } + + fieldmask := func(paths ...string) *fieldmaskpb.FieldMask { + return &fieldmaskpb.FieldMask{Paths: paths} + } + + v := vault.NewTestVaultServer(t, vault.WithTestVaultTLS(vault.TestClientTLS)) + _, token := v.CreateToken(t) + _ = token + + testExtensionBytes, _ := json.Marshal(map[string]string{"permit-pty": ""}) + testCriticalOptionsBytes, _ := json.Marshal(map[string]string{"option-a": "set-a"}) + + successCases := []struct { + name string + opts []vault.Option + req *pbs.UpdateCredentialLibraryRequest + res func(*pb.CredentialLibrary) *pb.CredentialLibrary + }{ + { + name: "name and description", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask("name", "description"), + Item: &pb.CredentialLibrary{ + Name: wrapperspb.String("basic"), + Description: wrapperspb.String("basic"), + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.Name = wrapperspb.String("basic") + out.Description = wrapperspb.String("basic") + return out + }, + }, + { + name: "update username", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask(sshCertUsernameField), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Username: wrapperspb.String("changed-username"), + }, + }, + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.GetVaultSshCertificateCredentialLibraryAttributes().Username = wrapperspb.String("changed-username") + return out + }, + }, + { + name: "update key type and key bits", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask("attributes.key_type", "attributes.key_bits"), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyType: wrapperspb.String(vault.KeyTypeRsa), + KeyBits: wrapperspb.UInt32(2048), + }, + }, + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.GetVaultSshCertificateCredentialLibraryAttributes().KeyType = wrapperspb.String("rsa") + out.GetVaultSshCertificateCredentialLibraryAttributes().KeyBits = wrapperspb.UInt32(2048) + return out + }, + }, + { + name: "update path", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask(vaultPathField), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + Path: wrapperspb.String("/ssh/issue/foo"), + }, + }, + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.GetVaultSshCertificateCredentialLibraryAttributes().Path = wrapperspb.String("/ssh/issue/foo") + return out + }, + }, + { + name: "update other attr fields", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask("attributes.ttl", "attributes.key_id", "attributes.critical_options.some", "attributes.extensions.permity-pty"), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyId: wrapperspb.String("id"), + CriticalOptions: map[string]string{"some": "option"}, + Extensions: map[string]string{"permit-pty": ""}, + Ttl: wrapperspb.String("2m"), + }, + }, + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.GetVaultSshCertificateCredentialLibraryAttributes().Ttl = wrapperspb.String("2m") + out.GetVaultSshCertificateCredentialLibraryAttributes().KeyId = wrapperspb.String("id") + out.GetVaultSshCertificateCredentialLibraryAttributes().CriticalOptions = map[string]string{"some": "option"} + out.GetVaultSshCertificateCredentialLibraryAttributes().Extensions = map[string]string{"permit-pty": ""} + return out + }, + }, + { + name: "clear critical options, extensions fields", + opts: []vault.Option{vault.WithExtensions(string(testExtensionBytes)), vault.WithCriticalOptions(string(testCriticalOptionsBytes))}, + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask("attributes.critical_options", "attributes.extensions.permit-pty"), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + CriticalOptions: nil, + Extensions: nil, + }, + }, + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.GetVaultSshCertificateCredentialLibraryAttributes().CriticalOptions = nil + out.GetVaultSshCertificateCredentialLibraryAttributes().Extensions = nil + return out + }, + }, + { + name: "set critical options while clearing extensions", + opts: []vault.Option{vault.WithExtensions(string(testExtensionBytes)), vault.WithCriticalOptions(string(testCriticalOptionsBytes))}, + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask("attributes.critical_options.option-b", "attributes.extensions"), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + CriticalOptions: map[string]string{"option-b": "set-b"}, + Extensions: nil, + }, + }, + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.GetVaultSshCertificateCredentialLibraryAttributes().CriticalOptions = map[string]string{"option-b": "set-b"} + out.GetVaultSshCertificateCredentialLibraryAttributes().Extensions = nil + return out + }, + }, + { + name: "set multiple critical options, extensions", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask("attributes.critical_options.option-a", "attributes.critical_options.option-b", "attributes.critical_options.option-c", + "attributes.extensions.permit-pty", "attributes.extensions.permit-port-forwarding", "attributes.extensions.permit-X11-forwarding"), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + CriticalOptions: map[string]string{"option-a": "set-a", "option-b": "set-b", "option-c": "set-c"}, + Extensions: map[string]string{"permit-pty": "", "permit-port-forwarding": "", "permit-X11-forwarding": ""}, + }, + }, + }, + }, + res: func(in *pb.CredentialLibrary) *pb.CredentialLibrary { + out := proto.Clone(in).(*pb.CredentialLibrary) + out.GetVaultSshCertificateCredentialLibraryAttributes().CriticalOptions = map[string]string{"option-a": "set-a", "option-b": "set-b", "option-c": "set-c"} + out.GetVaultSshCertificateCredentialLibraryAttributes().Extensions = map[string]string{"permit-pty": "", "permit-port-forwarding": "", "permit-X11-forwarding": ""} + return out + }, + }, + } + + for _, tc := range successCases { + t.Run(tc.name, func(t *testing.T) { + assert, require := assert.New(t), require.New(t) + st, cleanup := freshLibrary(tc.opts...) + defer cleanup() + + if tc.req.Item.GetVersion() == 0 { + tc.req.Item.Version = 1 + } + if tc.req.GetId() == "" { + tc.req.Id = st.GetPublicId() + } + resToChange, err := s.GetCredentialLibrary(ctx, &pbs.GetCredentialLibraryRequest{Id: st.GetPublicId()}) + require.NoError(err) + want := &pbs.UpdateCredentialLibraryResponse{Item: tc.res(resToChange.GetItem())} + + got, gErr := s.UpdateCredentialLibrary(ctx, tc.req) + require.NoError(gErr) + require.NotNil(got) + + gotUpdateTime := got.GetItem().GetUpdatedTime() + created := st.GetCreateTime().GetTimestamp() + assert.True(gotUpdateTime.AsTime().After(created.AsTime()), "Should have been updated after it's creation. Was updated %v, which is after %v", gotUpdateTime, created) + + want.Item.UpdatedTime = got.Item.UpdatedTime + + assert.EqualValues(2, got.Item.Version) + want.Item.Version = 2 + + assert.Empty(cmp.Diff(got, want, protocmp.Transform())) + }) + } + + vl, cleanup := freshLibrary() + defer cleanup() + + errCases := []struct { + name string + path string + item *pb.CredentialLibrary + }{ + { + name: "read only type", + path: "type", + item: &pb.CredentialLibrary{Type: "something"}, + }, + { + name: "read only store_id", + path: "store_id", + item: &pb.CredentialLibrary{CredentialStoreId: diffStore.GetPublicId()}, + }, + { + name: "read only updated_time", + path: "updated_time", + item: &pb.CredentialLibrary{UpdatedTime: timestamppb.Now()}, + }, + { + name: "read only created_time", + path: "created_time", + item: &pb.CredentialLibrary{UpdatedTime: timestamppb.Now()}, + }, + { + name: "read only authorized actions", + path: "authorized actions", + item: &pb.CredentialLibrary{AuthorizedActions: append(testAuthorizedActions, "another")}, + }, + { + name: "read only credential type", + path: "credential_type", + item: &pb.CredentialLibrary{CredentialType: string(credential.UsernamePasswordType)}, + }, + } + for _, tc := range errCases { + t.Run(tc.name, func(t *testing.T) { + req := &pbs.UpdateCredentialLibraryRequest{ + Id: vl.GetPublicId(), + Item: tc.item, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{tc.path}}, + } + req.Item.Version = vl.Version + + got, gErr := s.UpdateCredentialLibrary(ctx, req) + assert.Error(t, gErr) + assert.Truef(t, errors.Is(gErr, handlers.ApiErrorWithCode(codes.InvalidArgument)), "got error %v, wanted invalid argument", gErr) + assert.Nil(t, got) + }) + } + vErrs := []struct { + name string + req *pbs.UpdateCredentialLibraryRequest + errContains string + }{ + { + name: "invalid key type key bits combination", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask(keyBitsField, keyTypeField), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyType: wrapperspb.String(vault.KeyTypeEcdsa), + KeyBits: wrapperspb.UInt32(2048), + }, + }, + }, + }, + errContains: "Invalid bit size 2048 for key type ecdsa", + }, + { + name: "invalid key type", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask(keyTypeField), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyType: wrapperspb.String("unknown-type"), + }, + }, + }, + }, + errContains: "If set, value must be 'ed25519', 'ecdsa', or 'rsa'.", + }, + { + name: "invalid key bits", + req: &pbs.UpdateCredentialLibraryRequest{ + UpdateMask: fieldmask(keyBitsField), + Item: &pb.CredentialLibrary{ + Type: vault.SSHCertificateLibrarySubtype.String(), + Attrs: &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{ + VaultSshCertificateCredentialLibraryAttributes: &pb.VaultSSHCertificateCredentialLibraryAttributes{ + KeyBits: wrapperspb.UInt32(1234), + }, + }, + }, + }, + errContains: "Invalid bit size 1234", + }, + } + for _, tc := range vErrs { + t.Run(tc.name, func(t *testing.T) { + scl, cleanup := freshLibrary() + defer cleanup() + + if tc.req.Item.GetVersion() == 0 { + tc.req.Item.Version = 1 + } + if tc.req.GetId() == "" { + tc.req.Id = scl.GetPublicId() + } + got, gErr := s.UpdateCredentialLibrary(ctx, tc.req) + if gErr != nil { + assert.Contains(t, gErr.Error(), tc.errContains) + assert.Nil(t, got) + } + }) + } +} diff --git a/internal/daemon/controller/handlers/targets/tcp/target_service_test.go b/internal/daemon/controller/handlers/targets/tcp/target_service_test.go index d48fe1287..63ec28b42 100644 --- a/internal/daemon/controller/handlers/targets/tcp/target_service_test.go +++ b/internal/daemon/controller/handlers/targets/tcp/target_service_test.go @@ -2516,6 +2516,7 @@ func TestAuthorizeSession(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("Library Name"), Description: wrapperspb.String("Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: &wrapperspb.StringValue{ @@ -2629,7 +2630,7 @@ func TestAuthorizeSession(t *testing.T) { Name: clsResp.GetItem().GetName().GetValue(), Description: clsResp.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), }, }}, // TODO: validate the contents of the authorization token is what is expected @@ -2758,6 +2759,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("Usernamepassword Library"), Description: wrapperspb.String("Usernamepassword Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("secret", "data", "default-userpass")), @@ -2772,6 +2774,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("Unspecified Library"), Description: wrapperspb.String("Unspecified Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("secret", "data", "default-userpass")), @@ -2789,6 +2792,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("Usernamepassword Mapping Library"), Description: wrapperspb.String("Usernamepassword Mapping Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("secret", "data", "non-default-userpass")), @@ -2860,6 +2864,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("SSH Private Key Library"), Description: wrapperspb.String("SSH Private Key Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("secret", "data", "default-sshpk")), @@ -2878,6 +2883,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("SSH Private Key Mapping Library"), Description: wrapperspb.String("SSH Private Key Mapping Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("secret", "data", "non-default-sshpk")), @@ -2900,6 +2906,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("SSH Private Key With Passphrase Library"), Description: wrapperspb.String("SSH Private Key Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("secret", "data", "default-sshpk-with-pass")), @@ -2919,6 +2926,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { CredentialStoreId: vaultStore.GetPublicId(), Name: wrapperspb.String("SSH Private Key With Passphrase Mapping Library"), Description: wrapperspb.String("SSH Private Key Mapping Library Description"), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("secret", "data", "non-default-sshpk-with-pass")), @@ -2955,7 +2963,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { Name: clsRespUnspecified.GetItem().GetName().GetValue(), Description: clsRespUnspecified.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), }, }, }, @@ -2971,7 +2979,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { Name: clsRespUsernamePassword.GetItem().GetName().GetValue(), Description: clsRespUsernamePassword.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), CredentialType: string(credential.UsernamePasswordType), }, Credential: func() *structpb.Struct { @@ -2997,7 +3005,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { Name: clsRespUsernamePasswordWithMapping.GetItem().GetName().GetValue(), Description: clsRespUsernamePasswordWithMapping.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), CredentialType: string(credential.UsernamePasswordType), }, Credential: func() *structpb.Struct { @@ -3075,7 +3083,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { Name: clsRespSshPrivateKey.GetItem().GetName().GetValue(), Description: clsRespSshPrivateKey.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), CredentialType: string(credential.SshPrivateKeyType), }, Credential: func() *structpb.Struct { @@ -3101,7 +3109,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { Name: clsRespSshPrivateKeyWithMapping.GetItem().GetName().GetValue(), Description: clsRespSshPrivateKeyWithMapping.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), CredentialType: string(credential.SshPrivateKeyType), }, Credential: func() *structpb.Struct { @@ -3154,7 +3162,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { Name: clsRespSshPrivateKeyWithPass.GetItem().GetName().GetValue(), Description: clsRespSshPrivateKeyWithPass.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), CredentialType: string(credential.SshPrivateKeyType), }, Credential: func() *structpb.Struct { @@ -3181,7 +3189,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { Name: clsRespSshPrivateKeyWithPassWithMapping.GetItem().GetName().GetValue(), Description: clsRespSshPrivateKeyWithPassWithMapping.GetItem().GetDescription().GetValue(), CredentialStoreId: vaultStore.GetPublicId(), - Type: vault.Subtype.String(), + Type: vault.GenericLibrarySubtype.String(), CredentialType: string(credential.SshPrivateKeyType), }, Credential: func() *structpb.Struct { @@ -3392,6 +3400,7 @@ func TestAuthorizeSession_Errors(t *testing.T) { clsResp, err := credService.CreateCredentialLibrary(ctx, &pbs.CreateCredentialLibraryRequest{Item: &credlibpb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), Description: wrapperspb.String(fmt.Sprintf("Library Description for target %q", tar.GetName())), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("database", "creds", "opened")), @@ -3416,6 +3425,7 @@ func TestAuthorizeSession_Errors(t *testing.T) { clsResp, err := credService.CreateCredentialLibrary(ctx, &pbs.CreateCredentialLibraryRequest{Item: &credlibpb.CredentialLibrary{ CredentialStoreId: store.GetPublicId(), Description: wrapperspb.String(fmt.Sprintf("Library Description for target %q", tar.GetName())), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String("bad path"), @@ -3440,6 +3450,7 @@ func TestAuthorizeSession_Errors(t *testing.T) { clsResp, err := credService.CreateCredentialLibrary(ctx, &pbs.CreateCredentialLibraryRequest{Item: &credlibpb.CredentialLibrary{ CredentialStoreId: expiredStore.GetPublicId(), Description: wrapperspb.String(fmt.Sprintf("Library Description for target %q", tar.GetName())), + Type: vault.GenericLibrarySubtype.String(), Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{ VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{ Path: wrapperspb.String(path.Join("database", "creds", "opened")), diff --git a/internal/proto/controller/api/resources/credentiallibraries/v1/credential_library.proto b/internal/proto/controller/api/resources/credentiallibraries/v1/credential_library.proto index e67589c53..fe6fb8826 100644 --- a/internal/proto/controller/api/resources/credentiallibraries/v1/credential_library.proto +++ b/internal/proto/controller/api/resources/credentiallibraries/v1/credential_library.proto @@ -17,10 +17,7 @@ message CredentialLibrary { string id = 10; // @gotags: `class:"public"` // The ID of the Credential Store of which this Credential Library is a part. - string credential_store_id = 20 [ - json_name = "credential_store_id", - (controller.custom_options.v1.subtype_source_id) = true - ]; // @gotags: `class:"public"` + string credential_store_id = 20 [json_name = "credential_store_id"]; // @gotags: `class:"public"` // Output only. Scope information for this Credential Library. resources.scopes.v1.ScopeInfo scope = 30; @@ -67,6 +64,16 @@ message CredentialLibrary { (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.subtype) = "vault" ]; + VaultSSHCertificateCredentialLibraryAttributes vault_ssh_certificate_credential_library_attributes = 102 [ + (google.api.field_visibility).restriction = "INTERNAL", + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.subtype) = "vault-ssh-certificate" + ]; + VaultCredentialLibraryAttributes vault_generic_credential_library_attributes = 103 [ + (google.api.field_visibility).restriction = "INTERNAL", + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.subtype) = "vault-generic" + ]; } // Output only. The available actions on this resource for this user. @@ -116,3 +123,78 @@ message VaultCredentialLibraryAttributes { } ]; // @gotags: `class:"secret"` } + +// The attributes of a vault SSH Certificate Credential Library. +message VaultSSHCertificateCredentialLibraryAttributes { + // The path in Vault to request credentials from. + google.protobuf.StringValue path = 10 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.path" + that: "VaultPath" + } + ]; // @gotags: `class:"public"` + + // The username to use when making an SSH connection. + google.protobuf.StringValue username = 20 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.username" + that: "Username" + } + ]; // @gotags: `class:"sensitive"` + + // The key type to use when generating an SSH private key. + google.protobuf.StringValue key_type = 30 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.key_type" + that: "KeyType" + } + ]; // @gotags: `class:"public"` + + // The number of bits to use to generate an SSH private key. + google.protobuf.UInt32Value key_bits = 40 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.key_bits" + that: "KeyBits" + } + ]; // @gotags: `class:"public"` + + // The requested time to live for the certificate. + google.protobuf.StringValue ttl = 50 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.ttl" + that: "Ttl" + } + ]; // @gotags: `class:"public"` + + // The key id that the created certificate should have. + google.protobuf.StringValue key_id = 60 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.key_id" + that: "KeyId" + } + ]; // @gotags: `class:"public"` + + // The critical options that the certificate should be signed for. + map critical_options = 70 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.critical_options" + that: "CriticalOptions" + } + ]; // @gotags: `class:"public"` + + // The extensions that the certificate should be signed for. + map extensions = 80 [ + (custom_options.v1.generate_sdk_option) = true, + (custom_options.v1.mask_mapping) = { + this: "attributes.extensions" + that: "Extensions" + } + ]; // @gotags: `class:"public"` +} diff --git a/internal/tests/api/credentiallibraries/credentiallibrary_test.go b/internal/tests/api/credentiallibraries/credentiallibrary_test.go index 2016c92be..60a5684df 100644 --- a/internal/tests/api/credentiallibraries/credentiallibrary_test.go +++ b/internal/tests/api/credentiallibraries/credentiallibrary_test.go @@ -44,7 +44,7 @@ func TestList(t *testing.T) { expected = append(expected, &credentiallibraries.CredentialLibrary{Name: fmt.Sprint(i), Attributes: map[string]any{"vault_path": "something"}}) } - cl, err := lClient.Create(tc.Context(), cs.Item.Id, credentiallibraries.WithName(expected[0].Name), credentiallibraries.WithVaultCredentialLibraryPath("something")) + cl, err := lClient.Create(tc.Context(), cs.Item.Type, cs.Item.Id, credentiallibraries.WithName(expected[0].Name), credentiallibraries.WithVaultCredentialLibraryPath("something")) require.NoError(err) expected[0] = cl.Item @@ -53,7 +53,7 @@ func TestList(t *testing.T) { assert.ElementsMatch(comparableSetSlice(expected[:1]), comparableSetSlice(ul.Items)) for i := 1; i < 10; i++ { - cl, err = lClient.Create(tc.Context(), cs.Item.Id, credentiallibraries.WithName(expected[i].Name), credentiallibraries.WithVaultCredentialLibraryPath("something")) + cl, err = lClient.Create(tc.Context(), cs.Item.Type, cs.Item.Id, credentiallibraries.WithName(expected[i].Name), credentiallibraries.WithVaultCredentialLibraryPath("something")) require.NoError(err) expected[i] = cl.Item } @@ -115,8 +115,9 @@ func TestCrud(t *testing.T) { lClient := credentiallibraries.NewClient(client) - r, err := lClient.Create(tc.Context(), cs.Item.Id, credentiallibraries.WithName("foo"), + r, err := lClient.Create(tc.Context(), cs.Item.Type, cs.Item.Id, credentiallibraries.WithName("foo"), credentiallibraries.WithVaultCredentialLibraryPath("something")) + require.Nil(err) checkResource(t, "create", r.Item, err, "foo", 1) r, err = lClient.Read(tc.Context(), r.Item.Id) @@ -157,7 +158,7 @@ func TestErrors(t *testing.T) { lClient := credentiallibraries.NewClient(client) - l, err := lClient.Create(tc.Context(), cs.Item.Id, credentiallibraries.WithName("foo"), + l, err := lClient.Create(tc.Context(), cs.Item.Type, cs.Item.Id, credentiallibraries.WithName("foo"), credentiallibraries.WithVaultCredentialLibraryPath("something")) require.NoError(err) assert.NotNil(l) @@ -178,7 +179,7 @@ func TestErrors(t *testing.T) { assert.NotNil(apiErr) assert.EqualValues(http.StatusNotFound, apiErr.Response().StatusCode()) - l, err = lClient.Create(tc.Context(), cs.Item.Id, credentiallibraries.WithName("foo")) + l, err = lClient.Create(tc.Context(), cs.Item.Type, cs.Item.Id, credentiallibraries.WithName("foo")) require.Error(err) apiErr = api.AsServerError(err) assert.NotNil(apiErr) diff --git a/internal/tests/api/targets/target_test.go b/internal/tests/api/targets/target_test.go index 90685d7a3..dd4ee9a26 100644 --- a/internal/tests/api/targets/target_test.go +++ b/internal/tests/api/targets/target_test.go @@ -86,11 +86,11 @@ func TestCredentialSourcesASD(t *testing.T) { require.NotNil(csVault) lClient := credentiallibraries.NewClient(client) - lib1, err := lClient.Create(tc.Context(), csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something1")) + lib1, err := lClient.Create(tc.Context(), csVault.Item.Type, csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something1")) require.NoError(err) require.NotNil(lib1) - lib2, err := lClient.Create(tc.Context(), csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something2")) + lib2, err := lClient.Create(tc.Context(), csVault.Item.Type, csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something2")) require.NoError(err) require.NotNil(lib2) @@ -204,11 +204,11 @@ func TestDeprecatedCredentialSourcesASD(t *testing.T) { require.NotNil(csVault) lClient := credentiallibraries.NewClient(client) - lib1, err := lClient.Create(tc.Context(), csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something1")) + lib1, err := lClient.Create(tc.Context(), csVault.Item.Type, csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something1")) require.NoError(err) require.NotNil(lib1) - lib2, err := lClient.Create(tc.Context(), csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something2")) + lib2, err := lClient.Create(tc.Context(), csVault.Item.Type, csVault.Item.Id, credentiallibraries.WithVaultCredentialLibraryPath("something2")) require.NoError(err) require.NotNil(lib2) diff --git a/sdk/pbs/controller/api/resources/credentiallibraries/credential_library.pb.go b/sdk/pbs/controller/api/resources/credentiallibraries/credential_library.pb.go index db9d960b5..3d170f99f 100644 --- a/sdk/pbs/controller/api/resources/credentiallibraries/credential_library.pb.go +++ b/sdk/pbs/controller/api/resources/credentiallibraries/credential_library.pb.go @@ -55,6 +55,8 @@ type CredentialLibrary struct { // // *CredentialLibrary_Attributes // *CredentialLibrary_VaultCredentialLibraryAttributes + // *CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes + // *CredentialLibrary_VaultGenericCredentialLibraryAttributes Attrs isCredentialLibrary_Attrs `protobuf_oneof:"attrs"` // Output only. The available actions on this resource for this user. AuthorizedActions []string `protobuf:"bytes,300,rep,name=authorized_actions,proto3" json:"authorized_actions,omitempty" class:"public"` // @gotags: `class:"public"` @@ -180,6 +182,20 @@ func (x *CredentialLibrary) GetVaultCredentialLibraryAttributes() *VaultCredenti return nil } +func (x *CredentialLibrary) GetVaultSshCertificateCredentialLibraryAttributes() *VaultSSHCertificateCredentialLibraryAttributes { + if x, ok := x.GetAttrs().(*CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes); ok { + return x.VaultSshCertificateCredentialLibraryAttributes + } + return nil +} + +func (x *CredentialLibrary) GetVaultGenericCredentialLibraryAttributes() *VaultCredentialLibraryAttributes { + if x, ok := x.GetAttrs().(*CredentialLibrary_VaultGenericCredentialLibraryAttributes); ok { + return x.VaultGenericCredentialLibraryAttributes + } + return nil +} + func (x *CredentialLibrary) GetAuthorizedActions() []string { if x != nil { return x.AuthorizedActions @@ -214,10 +230,23 @@ type CredentialLibrary_VaultCredentialLibraryAttributes struct { VaultCredentialLibraryAttributes *VaultCredentialLibraryAttributes `protobuf:"bytes,101,opt,name=vault_credential_library_attributes,json=vaultCredentialLibraryAttributes,proto3,oneof"` } +type CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes struct { + VaultSshCertificateCredentialLibraryAttributes *VaultSSHCertificateCredentialLibraryAttributes `protobuf:"bytes,102,opt,name=vault_ssh_certificate_credential_library_attributes,json=vaultSshCertificateCredentialLibraryAttributes,proto3,oneof"` +} + +type CredentialLibrary_VaultGenericCredentialLibraryAttributes struct { + VaultGenericCredentialLibraryAttributes *VaultCredentialLibraryAttributes `protobuf:"bytes,103,opt,name=vault_generic_credential_library_attributes,json=vaultGenericCredentialLibraryAttributes,proto3,oneof"` +} + func (*CredentialLibrary_Attributes) isCredentialLibrary_Attrs() {} func (*CredentialLibrary_VaultCredentialLibraryAttributes) isCredentialLibrary_Attrs() {} +func (*CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes) isCredentialLibrary_Attrs() { +} + +func (*CredentialLibrary_VaultGenericCredentialLibraryAttributes) isCredentialLibrary_Attrs() {} + // The attributes of a vault typed Credential Library. type VaultCredentialLibraryAttributes struct { state protoimpl.MessageState @@ -285,6 +314,118 @@ func (x *VaultCredentialLibraryAttributes) GetHttpRequestBody() *wrapperspb.Stri return nil } +// The attributes of a vault SSH Certificate Credential Library. +type VaultSSHCertificateCredentialLibraryAttributes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The path in Vault to request credentials from. + Path *wrapperspb.StringValue `protobuf:"bytes,10,opt,name=path,proto3" json:"path,omitempty" class:"public"` // @gotags: `class:"public"` + // The username to use when making an SSH connection. + Username *wrapperspb.StringValue `protobuf:"bytes,20,opt,name=username,proto3" json:"username,omitempty" class:"sensitive"` // @gotags: `class:"sensitive"` + // The key type to use when generating an SSH private key. + KeyType *wrapperspb.StringValue `protobuf:"bytes,30,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty" class:"public"` // @gotags: `class:"public"` + // The number of bits to use to generate an SSH private key. + KeyBits *wrapperspb.UInt32Value `protobuf:"bytes,40,opt,name=key_bits,json=keyBits,proto3" json:"key_bits,omitempty" class:"public"` // @gotags: `class:"public"` + // The requested time to live for the certificate. + Ttl *wrapperspb.StringValue `protobuf:"bytes,50,opt,name=ttl,proto3" json:"ttl,omitempty" class:"public"` // @gotags: `class:"public"` + // The key id that the created certificate should have. + KeyId *wrapperspb.StringValue `protobuf:"bytes,60,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty" class:"public"` // @gotags: `class:"public"` + // The critical options that the certificate should be signed for. + CriticalOptions map[string]string `protobuf:"bytes,70,rep,name=critical_options,json=criticalOptions,proto3" json:"critical_options,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" class:"public"` // @gotags: `class:"public"` + // The extensions that the certificate should be signed for. + Extensions map[string]string `protobuf:"bytes,80,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" class:"public"` // @gotags: `class:"public"` +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) Reset() { + *x = VaultSSHCertificateCredentialLibraryAttributes{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_resources_credentiallibraries_v1_credential_library_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VaultSSHCertificateCredentialLibraryAttributes) ProtoMessage() {} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_resources_credentiallibraries_v1_credential_library_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VaultSSHCertificateCredentialLibraryAttributes.ProtoReflect.Descriptor instead. +func (*VaultSSHCertificateCredentialLibraryAttributes) Descriptor() ([]byte, []int) { + return file_controller_api_resources_credentiallibraries_v1_credential_library_proto_rawDescGZIP(), []int{2} +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetPath() *wrapperspb.StringValue { + if x != nil { + return x.Path + } + return nil +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetUsername() *wrapperspb.StringValue { + if x != nil { + return x.Username + } + return nil +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetKeyType() *wrapperspb.StringValue { + if x != nil { + return x.KeyType + } + return nil +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetKeyBits() *wrapperspb.UInt32Value { + if x != nil { + return x.KeyBits + } + return nil +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetTtl() *wrapperspb.StringValue { + if x != nil { + return x.Ttl + } + return nil +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetKeyId() *wrapperspb.StringValue { + if x != nil { + return x.KeyId + } + return nil +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetCriticalOptions() map[string]string { + if x != nil { + return x.CriticalOptions + } + return nil +} + +func (x *VaultSSHCertificateCredentialLibraryAttributes) GetExtensions() map[string]string { + if x != nil { + return x.Extensions + } + return nil +} + var File_controller_api_resources_credentiallibraries_v1_credential_library_proto protoreflect.FileDescriptor var file_controller_api_resources_credentiallibraries_v1_credential_library_proto_rawDesc = []byte{ @@ -309,99 +450,199 @@ var file_controller_api_resources_credentiallibraries_v1_credential_library_prot 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x07, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x0b, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x13, 0x63, 0x72, 0x65, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xa0, 0xe3, 0x29, 0x01, 0x52, 0x13, 0x63, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, - 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, - 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x28, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x42, 0x14, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x0c, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x62, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x32, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x22, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x4a, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x64, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x0f, 0xa0, - 0xda, 0x29, 0x01, 0x9a, 0xe3, 0x29, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x48, 0x00, - 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0xc1, 0x01, 0x0a, - 0x23, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x51, 0x2e, 0x63, 0x6f, 0x6e, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, - 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x75, - 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, - 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x1d, 0xa0, - 0xda, 0x29, 0x01, 0x9a, 0xe3, 0x29, 0x05, 0x76, 0x61, 0x75, 0x6c, 0x74, 0xfa, 0xd2, 0xe4, 0x93, - 0x02, 0x0a, 0x12, 0x08, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x48, 0x00, 0x52, 0x20, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, - 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x12, 0x2f, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x2f, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0xb6, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xa0, 0xda, 0x29, - 0x01, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x62, 0x0a, 0x1c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, - 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, - 0x65, 0x73, 0x18, 0xc0, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x42, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x1c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x76, 0x65, - 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x61, 0x74, 0x74, 0x72, 0x73, 0x22, - 0xee, 0x02, 0x0a, 0x20, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0a, 0x20, 0x01, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, + 0x12, 0x46, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x14, 0xa0, 0xda, + 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x62, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x22, 0xa0, 0xda, 0x29, + 0x01, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0c, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x46, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x5a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x4a, 0x0a, 0x0a, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x0f, 0xa0, 0xda, 0x29, 0x01, 0x9a, 0xe3, 0x29, + 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0xc1, 0x01, 0x0a, 0x23, 0x76, 0x61, 0x75, 0x6c, 0x74, + 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x62, 0x72, + 0x61, 0x72, 0x79, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x65, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, + 0x69, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x1d, 0xa0, 0xda, 0x29, 0x01, 0x9a, 0xe3, 0x29, + 0x05, 0x76, 0x61, 0x75, 0x6c, 0x74, 0xfa, 0xd2, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x49, 0x4e, + 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x48, 0x00, 0x52, 0x20, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0xfd, 0x01, 0x0a, 0x33, 0x76, + 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, + 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x5f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x69, + 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x75, 0x6c, 0x74, + 0x53, 0x53, 0x48, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x2d, 0xa0, 0xda, 0x29, 0x01, 0x9a, + 0xe3, 0x29, 0x15, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2d, 0x73, 0x73, 0x68, 0x2d, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0xfa, 0xd2, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, + 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x48, 0x00, 0x52, 0x2e, 0x76, 0x61, 0x75, 0x6c, + 0x74, 0x53, 0x73, 0x68, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0xd8, 0x01, 0x0a, 0x2b, 0x76, + 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x5f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x51, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x42, 0x25, 0xa0, 0xda, 0x29, 0x01, 0x9a, 0xe3, 0x29, 0x0d, 0x76, 0x61, 0x75, + 0x6c, 0x74, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0xfa, 0xd2, 0xe4, 0x93, 0x02, 0x0a, + 0x12, 0x08, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x48, 0x00, 0x52, 0x27, 0x76, 0x61, + 0x75, 0x6c, 0x74, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0xb6, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x62, 0x0a, 0x1c, 0x63, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0xc0, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x1c, 0x63, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x61, + 0x74, 0x74, 0x72, 0x73, 0x22, 0xee, 0x02, 0x0a, 0x20, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x24, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1c, 0x0a, + 0x0f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x61, 0x74, 0x68, + 0x12, 0x09, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x12, 0x6c, 0x0a, 0x0b, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2c, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x24, 0x0a, 0x16, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x0a, 0x48, 0x74, 0x74, 0x70, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x52, 0x0b, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x83, 0x01, 0x0a, 0x11, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x37, 0xa0, 0xda, 0x29, 0x01, 0xc2, + 0xdd, 0x29, 0x2f, 0x0a, 0x1c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f, 0x64, + 0x79, 0x12, 0x0f, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, + 0x64, 0x79, 0x52, 0x11, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xf1, 0x08, 0x0a, 0x2e, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x53, + 0x53, 0x48, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x42, 0x24, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1c, 0x0a, 0x0f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x12, + 0x09, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x12, 0x61, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x24, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1c, 0x0a, 0x0f, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x12, 0x09, 0x56, 0x61, 0x75, - 0x6c, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x6c, 0x0a, 0x0b, - 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x2c, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x24, 0x0a, 0x16, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x12, 0x0a, 0x48, 0x74, 0x74, 0x70, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0b, 0x68, - 0x74, 0x74, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x83, 0x01, 0x0a, 0x11, 0x68, - 0x74, 0x74, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f, 0x64, 0x79, - 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x37, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x2f, 0x0a, 0x1c, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x0f, 0x48, 0x74, - 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x11, 0x68, - 0x74, 0x74, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f, 0x64, 0x79, - 0x42, 0x68, 0x5a, 0x66, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, - 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x69, 0x62, - 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x3b, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x42, 0x27, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1f, 0x0a, 0x13, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x5f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x42, 0x26, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1e, 0x0a, 0x13, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6b, 0x65, 0x79, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x5f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x69, 0x74, 0x73, + 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x42, 0x26, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1e, 0x0a, 0x13, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x62, + 0x69, 0x74, 0x73, 0x12, 0x07, 0x4b, 0x65, 0x79, 0x42, 0x69, 0x74, 0x73, 0x52, 0x07, 0x6b, 0x65, + 0x79, 0x42, 0x69, 0x74, 0x73, 0x12, 0x4d, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x32, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x42, 0x1d, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x15, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x74, 0x74, 0x6c, 0x12, 0x03, 0x54, 0x74, 0x6c, 0x52, + 0x03, 0x74, 0x74, 0x6c, 0x12, 0x57, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x3c, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x42, 0x22, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x11, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x12, + 0x05, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x12, 0xd7, 0x01, + 0x0a, 0x10, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x46, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x74, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x69, + 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x75, 0x6c, 0x74, + 0x53, 0x53, 0x48, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x36, + 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x2e, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2e, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xbc, 0x01, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x50, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x6f, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, + 0x61, 0x75, 0x6c, 0x74, 0x53, 0x53, 0x48, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4c, 0x69, 0x62, 0x72, + 0x61, 0x72, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x2b, 0xa0, + 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x23, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0a, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, 0x0f, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x68, 0x5a, 0x66, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, + 0x62, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x3b, + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, + 0x69, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -416,32 +657,46 @@ func file_controller_api_resources_credentiallibraries_v1_credential_library_pro return file_controller_api_resources_credentiallibraries_v1_credential_library_proto_rawDescData } -var file_controller_api_resources_credentiallibraries_v1_credential_library_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_controller_api_resources_credentiallibraries_v1_credential_library_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_controller_api_resources_credentiallibraries_v1_credential_library_proto_goTypes = []interface{}{ - (*CredentialLibrary)(nil), // 0: controller.api.resources.credentiallibraries.v1.CredentialLibrary - (*VaultCredentialLibraryAttributes)(nil), // 1: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes - (*scopes.ScopeInfo)(nil), // 2: controller.api.resources.scopes.v1.ScopeInfo - (*wrapperspb.StringValue)(nil), // 3: google.protobuf.StringValue - (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp - (*structpb.Struct)(nil), // 5: google.protobuf.Struct + (*CredentialLibrary)(nil), // 0: controller.api.resources.credentiallibraries.v1.CredentialLibrary + (*VaultCredentialLibraryAttributes)(nil), // 1: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes + (*VaultSSHCertificateCredentialLibraryAttributes)(nil), // 2: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes + nil, // 3: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.CriticalOptionsEntry + nil, // 4: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.ExtensionsEntry + (*scopes.ScopeInfo)(nil), // 5: controller.api.resources.scopes.v1.ScopeInfo + (*wrapperspb.StringValue)(nil), // 6: google.protobuf.StringValue + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp + (*structpb.Struct)(nil), // 8: google.protobuf.Struct + (*wrapperspb.UInt32Value)(nil), // 9: google.protobuf.UInt32Value } var file_controller_api_resources_credentiallibraries_v1_credential_library_proto_depIdxs = []int32{ - 2, // 0: controller.api.resources.credentiallibraries.v1.CredentialLibrary.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo - 3, // 1: controller.api.resources.credentiallibraries.v1.CredentialLibrary.name:type_name -> google.protobuf.StringValue - 3, // 2: controller.api.resources.credentiallibraries.v1.CredentialLibrary.description:type_name -> google.protobuf.StringValue - 4, // 3: controller.api.resources.credentiallibraries.v1.CredentialLibrary.created_time:type_name -> google.protobuf.Timestamp - 4, // 4: controller.api.resources.credentiallibraries.v1.CredentialLibrary.updated_time:type_name -> google.protobuf.Timestamp - 5, // 5: controller.api.resources.credentiallibraries.v1.CredentialLibrary.attributes:type_name -> google.protobuf.Struct + 5, // 0: controller.api.resources.credentiallibraries.v1.CredentialLibrary.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo + 6, // 1: controller.api.resources.credentiallibraries.v1.CredentialLibrary.name:type_name -> google.protobuf.StringValue + 6, // 2: controller.api.resources.credentiallibraries.v1.CredentialLibrary.description:type_name -> google.protobuf.StringValue + 7, // 3: controller.api.resources.credentiallibraries.v1.CredentialLibrary.created_time:type_name -> google.protobuf.Timestamp + 7, // 4: controller.api.resources.credentiallibraries.v1.CredentialLibrary.updated_time:type_name -> google.protobuf.Timestamp + 8, // 5: controller.api.resources.credentiallibraries.v1.CredentialLibrary.attributes:type_name -> google.protobuf.Struct 1, // 6: controller.api.resources.credentiallibraries.v1.CredentialLibrary.vault_credential_library_attributes:type_name -> controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes - 5, // 7: controller.api.resources.credentiallibraries.v1.CredentialLibrary.credential_mapping_overrides:type_name -> google.protobuf.Struct - 3, // 8: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes.path:type_name -> google.protobuf.StringValue - 3, // 9: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes.http_method:type_name -> google.protobuf.StringValue - 3, // 10: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes.http_request_body:type_name -> google.protobuf.StringValue - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 2, // 7: controller.api.resources.credentiallibraries.v1.CredentialLibrary.vault_ssh_certificate_credential_library_attributes:type_name -> controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes + 1, // 8: controller.api.resources.credentiallibraries.v1.CredentialLibrary.vault_generic_credential_library_attributes:type_name -> controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes + 8, // 9: controller.api.resources.credentiallibraries.v1.CredentialLibrary.credential_mapping_overrides:type_name -> google.protobuf.Struct + 6, // 10: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes.path:type_name -> google.protobuf.StringValue + 6, // 11: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes.http_method:type_name -> google.protobuf.StringValue + 6, // 12: controller.api.resources.credentiallibraries.v1.VaultCredentialLibraryAttributes.http_request_body:type_name -> google.protobuf.StringValue + 6, // 13: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.path:type_name -> google.protobuf.StringValue + 6, // 14: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.username:type_name -> google.protobuf.StringValue + 6, // 15: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.key_type:type_name -> google.protobuf.StringValue + 9, // 16: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.key_bits:type_name -> google.protobuf.UInt32Value + 6, // 17: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.ttl:type_name -> google.protobuf.StringValue + 6, // 18: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.key_id:type_name -> google.protobuf.StringValue + 3, // 19: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.critical_options:type_name -> controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.CriticalOptionsEntry + 4, // 20: controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.extensions:type_name -> controller.api.resources.credentiallibraries.v1.VaultSSHCertificateCredentialLibraryAttributes.ExtensionsEntry + 21, // [21:21] is the sub-list for method output_type + 21, // [21:21] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_controller_api_resources_credentiallibraries_v1_credential_library_proto_init() } @@ -474,10 +729,24 @@ func file_controller_api_resources_credentiallibraries_v1_credential_library_pro return nil } } + file_controller_api_resources_credentiallibraries_v1_credential_library_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VaultSSHCertificateCredentialLibraryAttributes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_controller_api_resources_credentiallibraries_v1_credential_library_proto_msgTypes[0].OneofWrappers = []interface{}{ (*CredentialLibrary_Attributes)(nil), (*CredentialLibrary_VaultCredentialLibraryAttributes)(nil), + (*CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes)(nil), + (*CredentialLibrary_VaultGenericCredentialLibraryAttributes)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -485,7 +754,7 @@ func file_controller_api_resources_credentiallibraries_v1_credential_library_pro GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controller_api_resources_credentiallibraries_v1_credential_library_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/testing/internal/e2e/tests/static_with_vault/credential_store_test.go b/testing/internal/e2e/tests/static_with_vault/credential_store_test.go index 339c7eb68..c29749193 100644 --- a/testing/internal/e2e/tests/static_with_vault/credential_store_test.go +++ b/testing/internal/e2e/tests/static_with_vault/credential_store_test.go @@ -256,7 +256,7 @@ func TestApiVaultCredentialStore(t *testing.T) { // Create a credential library for the private key clClient := credentiallibraries.NewClient(client) - newCredentialLibraryResult, err := clClient.Create(ctx, newCredentialStoreId, + newCredentialLibraryResult, err := clClient.Create(ctx, "vault", newCredentialStoreId, credentiallibraries.WithVaultCredentialLibraryPath(c.VaultSecretPath+"/data/"+privateKeySecretName), credentiallibraries.WithCredentialType("ssh_private_key"), ) @@ -265,7 +265,7 @@ func TestApiVaultCredentialStore(t *testing.T) { t.Logf("Created Credential Library: %s", newPrivateKeyCredentialLibraryId) // Create a credential library for the password - newCredentialLibraryResult, err = clClient.Create(ctx, newCredentialStoreId, + newCredentialLibraryResult, err = clClient.Create(ctx, "vault", newCredentialStoreId, credentiallibraries.WithVaultCredentialLibraryPath(c.VaultSecretPath+"/data/"+passwordSecretName), credentiallibraries.WithCredentialType("username_password"), )