feat(credentiallibraries): support vault ssh certificates

This commit is contained in:
Haotian authored and Timothy Messier committed 2023-02-02 17:43:16 +00:00
1 parent 3a78a74571
commit 43f0ba89cf
14 files changed
+2087 -239

No files matched your search

@@ -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
+168
View File
@@ -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
}
}
@@ -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)
}
+47 -1
View File
@@ -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,
@@ -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
}
+13 -12
View File
@@ -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,
},
},
@@ -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)
@@ -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")),
@@ -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<string, string> 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<string, string> extensions = 80 [
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.mask_mapping) = {
this: "attributes.extensions"
that: "Extensions"
}
]; // @gotags: `class:"public"`
}
@@ -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)
+4 -4
View File
@@ -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)
@@ -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,
},
@@ -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"),
)