From a67085f663e2a5b049ca7259044f79eee5022301 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 28 Jul 2022 18:17:30 -0400 Subject: [PATCH] Add methods to get attributes more easily in Go API (#2299) * Add methods to get attributes more easily in Go API * Add type check --- api/accounts/oidc_account_attributes.gen.go | 31 ++++++ .../password_account_attributes.gen.go | 31 ++++++ .../oidc_auth_method_attributes.gen.go | 31 ++++++ .../password_auth_method_attributes.gen.go | 31 ++++++ ...vault_credential_library_attributes.gen.go | 31 ++++++ .../ssh_private_key_attributes.gen.go | 31 ++++++ .../username_password_attributes.gen.go | 31 ++++++ .../vault_credential_store_attributes.gen.go | 31 ++++++ api/hosts/static_host_attributes.gen.go | 31 ++++++ .../oidc_managed_group_attributes.gen.go | 31 ++++++ api/targets/ssh_target_attributes.gen.go | 31 ++++++ api/targets/tcp_target_attributes.gen.go | 31 ++++++ internal/api/genapi/input.go | 96 ++++++++++++++----- internal/api/genapi/templates.go | 36 +++++++ 14 files changed, 480 insertions(+), 24 deletions(-) diff --git a/api/accounts/oidc_account_attributes.gen.go b/api/accounts/oidc_account_attributes.gen.go index c1ca25c0d..ffb6d77e7 100644 --- a/api/accounts/oidc_account_attributes.gen.go +++ b/api/accounts/oidc_account_attributes.gen.go @@ -1,6 +1,12 @@ // Code generated by "make api"; DO NOT EDIT. package accounts +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type OidcAccountAttributes struct { Issuer string `json:"issuer,omitempty"` Subject string `json:"subject,omitempty"` @@ -9,3 +15,28 @@ type OidcAccountAttributes struct { TokenClaims map[string]interface{} `json:"token_claims,omitempty"` UserinfoClaims map[string]interface{} `json:"userinfo_claims,omitempty"` } + +func AttributesMapToOidcAccountAttributes(in map[string]interface{}) (*OidcAccountAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out OidcAccountAttributes + 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 *Account) GetOidcAccountAttributes() (*OidcAccountAttributes, error) { + if pt.Type != "oidc" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but account is of type %s", "oidc", pt.Type) + } + return AttributesMapToOidcAccountAttributes(pt.Attributes) +} diff --git a/api/accounts/password_account_attributes.gen.go b/api/accounts/password_account_attributes.gen.go index 2e20d119c..36d3e364d 100644 --- a/api/accounts/password_account_attributes.gen.go +++ b/api/accounts/password_account_attributes.gen.go @@ -1,7 +1,38 @@ // Code generated by "make api"; DO NOT EDIT. package accounts +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type PasswordAccountAttributes struct { LoginName string `json:"login_name,omitempty"` Password string `json:"password,omitempty"` } + +func AttributesMapToPasswordAccountAttributes(in map[string]interface{}) (*PasswordAccountAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out PasswordAccountAttributes + 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 *Account) GetPasswordAccountAttributes() (*PasswordAccountAttributes, error) { + if pt.Type != "password" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but account is of type %s", "password", pt.Type) + } + return AttributesMapToPasswordAccountAttributes(pt.Attributes) +} diff --git a/api/authmethods/oidc_auth_method_attributes.gen.go b/api/authmethods/oidc_auth_method_attributes.gen.go index c07f357e4..f928e8b05 100644 --- a/api/authmethods/oidc_auth_method_attributes.gen.go +++ b/api/authmethods/oidc_auth_method_attributes.gen.go @@ -1,6 +1,12 @@ // Code generated by "make api"; DO NOT EDIT. package authmethods +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type OidcAuthMethodAttributes struct { State string `json:"state,omitempty"` Issuer string `json:"issuer,omitempty"` @@ -18,3 +24,28 @@ type OidcAuthMethodAttributes struct { DisableDiscoveredConfigValidation bool `json:"disable_discovered_config_validation,omitempty"` DryRun bool `json:"dry_run,omitempty"` } + +func AttributesMapToOidcAuthMethodAttributes(in map[string]interface{}) (*OidcAuthMethodAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out OidcAuthMethodAttributes + 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 *AuthMethod) GetOidcAuthMethodAttributes() (*OidcAuthMethodAttributes, error) { + if pt.Type != "oidc" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but auth-method is of type %s", "oidc", pt.Type) + } + return AttributesMapToOidcAuthMethodAttributes(pt.Attributes) +} diff --git a/api/authmethods/password_auth_method_attributes.gen.go b/api/authmethods/password_auth_method_attributes.gen.go index 32b389e63..d2cad94e8 100644 --- a/api/authmethods/password_auth_method_attributes.gen.go +++ b/api/authmethods/password_auth_method_attributes.gen.go @@ -1,7 +1,38 @@ // Code generated by "make api"; DO NOT EDIT. package authmethods +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type PasswordAuthMethodAttributes struct { MinLoginNameLength uint32 `json:"min_login_name_length,omitempty"` MinPasswordLength uint32 `json:"min_password_length,omitempty"` } + +func AttributesMapToPasswordAuthMethodAttributes(in map[string]interface{}) (*PasswordAuthMethodAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out PasswordAuthMethodAttributes + 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 *AuthMethod) GetPasswordAuthMethodAttributes() (*PasswordAuthMethodAttributes, error) { + if pt.Type != "password" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but auth-method is of type %s", "password", pt.Type) + } + return AttributesMapToPasswordAuthMethodAttributes(pt.Attributes) +} diff --git a/api/credentiallibraries/vault_credential_library_attributes.gen.go b/api/credentiallibraries/vault_credential_library_attributes.gen.go index 71b0c0162..8c7f359da 100644 --- a/api/credentiallibraries/vault_credential_library_attributes.gen.go +++ b/api/credentiallibraries/vault_credential_library_attributes.gen.go @@ -1,8 +1,39 @@ // Code generated by "make api"; DO NOT EDIT. package credentiallibraries +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type VaultCredentialLibraryAttributes struct { Path string `json:"path,omitempty"` HttpMethod string `json:"http_method,omitempty"` HttpRequestBody string `json:"http_request_body,omitempty"` } + +func AttributesMapToVaultCredentialLibraryAttributes(in map[string]interface{}) (*VaultCredentialLibraryAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out VaultCredentialLibraryAttributes + 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) GetVaultCredentialLibraryAttributes() (*VaultCredentialLibraryAttributes, error) { + if pt.Type != "vault" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but credential-library is of type %s", "vault", pt.Type) + } + return AttributesMapToVaultCredentialLibraryAttributes(pt.Attributes) +} diff --git a/api/credentials/ssh_private_key_attributes.gen.go b/api/credentials/ssh_private_key_attributes.gen.go index 3ec70fa1e..fc1ecc2a3 100644 --- a/api/credentials/ssh_private_key_attributes.gen.go +++ b/api/credentials/ssh_private_key_attributes.gen.go @@ -1,8 +1,39 @@ // Code generated by "make api"; DO NOT EDIT. package credentials +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type SshPrivateKeyAttributes struct { Username string `json:"username,omitempty"` PrivateKey string `json:"private_key,omitempty"` PrivateKeyHmac string `json:"private_key_hmac,omitempty"` } + +func AttributesMapToSshPrivateKeyAttributes(in map[string]interface{}) (*SshPrivateKeyAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out SshPrivateKeyAttributes + 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 *Credential) GetSshPrivateKeyAttributes() (*SshPrivateKeyAttributes, error) { + if pt.Type != "sshprivatekey" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but credential is of type %s", "sshprivatekey", pt.Type) + } + return AttributesMapToSshPrivateKeyAttributes(pt.Attributes) +} diff --git a/api/credentials/username_password_attributes.gen.go b/api/credentials/username_password_attributes.gen.go index e0923d0fc..0feaa5fb1 100644 --- a/api/credentials/username_password_attributes.gen.go +++ b/api/credentials/username_password_attributes.gen.go @@ -1,8 +1,39 @@ // Code generated by "make api"; DO NOT EDIT. package credentials +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type UsernamePasswordAttributes struct { Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` PasswordHmac string `json:"password_hmac,omitempty"` } + +func AttributesMapToUsernamePasswordAttributes(in map[string]interface{}) (*UsernamePasswordAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out UsernamePasswordAttributes + 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 *Credential) GetUsernamePasswordAttributes() (*UsernamePasswordAttributes, error) { + if pt.Type != "usernamepassword" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but credential is of type %s", "usernamepassword", pt.Type) + } + return AttributesMapToUsernamePasswordAttributes(pt.Attributes) +} diff --git a/api/credentialstores/vault_credential_store_attributes.gen.go b/api/credentialstores/vault_credential_store_attributes.gen.go index a3a27a713..d9871b9be 100644 --- a/api/credentialstores/vault_credential_store_attributes.gen.go +++ b/api/credentialstores/vault_credential_store_attributes.gen.go @@ -1,6 +1,12 @@ // Code generated by "make api"; DO NOT EDIT. package credentialstores +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type VaultCredentialStoreAttributes struct { Address string `json:"address,omitempty"` Namespace string `json:"namespace,omitempty"` @@ -14,3 +20,28 @@ type VaultCredentialStoreAttributes struct { ClientCertificateKeyHmac string `json:"client_certificate_key_hmac,omitempty"` WorkerFilter string `json:"worker_filter,omitempty"` } + +func AttributesMapToVaultCredentialStoreAttributes(in map[string]interface{}) (*VaultCredentialStoreAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out VaultCredentialStoreAttributes + 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 *CredentialStore) GetVaultCredentialStoreAttributes() (*VaultCredentialStoreAttributes, error) { + if pt.Type != "vault" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but credential-store is of type %s", "vault", pt.Type) + } + return AttributesMapToVaultCredentialStoreAttributes(pt.Attributes) +} diff --git a/api/hosts/static_host_attributes.gen.go b/api/hosts/static_host_attributes.gen.go index f16d27136..f42aeb7b7 100644 --- a/api/hosts/static_host_attributes.gen.go +++ b/api/hosts/static_host_attributes.gen.go @@ -1,6 +1,37 @@ // Code generated by "make api"; DO NOT EDIT. package hosts +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type StaticHostAttributes struct { Address string `json:"address,omitempty"` } + +func AttributesMapToStaticHostAttributes(in map[string]interface{}) (*StaticHostAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out StaticHostAttributes + 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 *Host) GetStaticHostAttributes() (*StaticHostAttributes, error) { + if pt.Type != "static" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but host is of type %s", "static", pt.Type) + } + return AttributesMapToStaticHostAttributes(pt.Attributes) +} diff --git a/api/managedgroups/oidc_managed_group_attributes.gen.go b/api/managedgroups/oidc_managed_group_attributes.gen.go index 73eba7540..5c40f988e 100644 --- a/api/managedgroups/oidc_managed_group_attributes.gen.go +++ b/api/managedgroups/oidc_managed_group_attributes.gen.go @@ -1,6 +1,37 @@ // Code generated by "make api"; DO NOT EDIT. package managedgroups +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type OidcManagedGroupAttributes struct { Filter string `json:"filter,omitempty"` } + +func AttributesMapToOidcManagedGroupAttributes(in map[string]interface{}) (*OidcManagedGroupAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out OidcManagedGroupAttributes + 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 *ManagedGroup) GetOidcManagedGroupAttributes() (*OidcManagedGroupAttributes, error) { + if pt.Type != "oidc" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but managed-group is of type %s", "oidc", pt.Type) + } + return AttributesMapToOidcManagedGroupAttributes(pt.Attributes) +} diff --git a/api/targets/ssh_target_attributes.gen.go b/api/targets/ssh_target_attributes.gen.go index 02d505f9c..c9c16346a 100644 --- a/api/targets/ssh_target_attributes.gen.go +++ b/api/targets/ssh_target_attributes.gen.go @@ -1,6 +1,37 @@ // Code generated by "make api"; DO NOT EDIT. package targets +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type SshTargetAttributes struct { DefaultPort uint32 `json:"default_port,omitempty"` } + +func AttributesMapToSshTargetAttributes(in map[string]interface{}) (*SshTargetAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out SshTargetAttributes + 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 *Target) GetSshTargetAttributes() (*SshTargetAttributes, error) { + if pt.Type != "ssh" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but target is of type %s", "ssh", pt.Type) + } + return AttributesMapToSshTargetAttributes(pt.Attributes) +} diff --git a/api/targets/tcp_target_attributes.gen.go b/api/targets/tcp_target_attributes.gen.go index f7918d6cc..c43101870 100644 --- a/api/targets/tcp_target_attributes.gen.go +++ b/api/targets/tcp_target_attributes.gen.go @@ -1,6 +1,37 @@ // Code generated by "make api"; DO NOT EDIT. package targets +import ( + "fmt" + + "github.com/mitchellh/mapstructure" +) + type TcpTargetAttributes struct { DefaultPort uint32 `json:"default_port,omitempty"` } + +func AttributesMapToTcpTargetAttributes(in map[string]interface{}) (*TcpTargetAttributes, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out TcpTargetAttributes + 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 *Target) GetTcpTargetAttributes() (*TcpTargetAttributes, error) { + if pt.Type != "tcp" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but target is of type %s", "tcp", pt.Type) + } + return AttributesMapToTcpTargetAttributes(pt.Attributes) +} diff --git a/internal/api/genapi/input.go b/internal/api/genapi/input.go index d64b35d58..6c08b223f 100644 --- a/internal/api/genapi/input.go +++ b/internal/api/genapi/input.go @@ -281,14 +281,22 @@ var inputStructs = []*structInfo{ }, // Auth Methods related resources { - inProto: &authmethods.PasswordAuthMethodAttributes{}, - outFile: "authmethods/password_auth_method_attributes.gen.go", - subtypeName: "PasswordAuthMethod", + inProto: &authmethods.PasswordAuthMethodAttributes{}, + outFile: "authmethods/password_auth_method_attributes.gen.go", + subtypeName: "PasswordAuthMethod", + parentTypeName: "AuthMethod", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { - inProto: &authmethods.OidcAuthMethodAttributes{}, - outFile: "authmethods/oidc_auth_method_attributes.gen.go", - subtypeName: "OidcAuthMethod", + inProto: &authmethods.OidcAuthMethodAttributes{}, + outFile: "authmethods/oidc_auth_method_attributes.gen.go", + subtypeName: "OidcAuthMethod", + parentTypeName: "AuthMethod", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &authmethods.OidcAuthMethodAuthenticateStartResponse{}, @@ -320,14 +328,22 @@ var inputStructs = []*structInfo{ }, // Accounts { - inProto: &accounts.PasswordAccountAttributes{}, - outFile: "accounts/password_account_attributes.gen.go", - subtypeName: "PasswordAccount", + inProto: &accounts.PasswordAccountAttributes{}, + outFile: "accounts/password_account_attributes.gen.go", + subtypeName: "PasswordAccount", + parentTypeName: "Account", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { - inProto: &accounts.OidcAccountAttributes{}, - outFile: "accounts/oidc_account_attributes.gen.go", - subtypeName: "OidcAccount", + inProto: &accounts.OidcAccountAttributes{}, + outFile: "accounts/oidc_account_attributes.gen.go", + subtypeName: "OidcAccount", + parentTypeName: "Account", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &accounts.Account{}, @@ -356,6 +372,10 @@ var inputStructs = []*structInfo{ SkipDefault: true, }, }, + parentTypeName: "ManagedGroup", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &managedgroups.ManagedGroup{}, @@ -389,9 +409,13 @@ var inputStructs = []*structInfo{ }, // Credentials { - inProto: &credentialstores.VaultCredentialStoreAttributes{}, - outFile: "credentialstores/vault_credential_store_attributes.gen.go", - subtypeName: "VaultCredentialStore", + inProto: &credentialstores.VaultCredentialStoreAttributes{}, + outFile: "credentialstores/vault_credential_store_attributes.gen.go", + subtypeName: "VaultCredentialStore", + parentTypeName: "CredentialStore", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &credentialstores.CredentialStore{}, @@ -437,6 +461,10 @@ var inputStructs = []*structInfo{ SkipDefault: true, }, }, + parentTypeName: "CredentialLibrary", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &credentiallibraries.CredentialLibrary{}, @@ -468,6 +496,10 @@ var inputStructs = []*structInfo{ SkipDefault: true, }, }, + parentTypeName: "Credential", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &credentials.SshPrivateKeyAttributes{}, @@ -483,6 +515,10 @@ var inputStructs = []*structInfo{ SkipDefault: true, }, }, + parentTypeName: "Credential", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &credentials.Credential{}, @@ -564,9 +600,13 @@ var inputStructs = []*structInfo{ createResponseTypes: true, }, { - inProto: &hosts.StaticHostAttributes{}, - outFile: "hosts/static_host_attributes.gen.go", - subtypeName: "StaticHost", + inProto: &hosts.StaticHostAttributes{}, + outFile: "hosts/static_host_attributes.gen.go", + subtypeName: "StaticHost", + parentTypeName: "Host", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &hostsets.HostSet{}, @@ -627,14 +667,22 @@ var inputStructs = []*structInfo{ subtypeName: "WorkerInfo", }, { - inProto: &targets.TcpTargetAttributes{}, - outFile: "targets/tcp_target_attributes.gen.go", - subtypeName: "TcpTarget", + inProto: &targets.TcpTargetAttributes{}, + outFile: "targets/tcp_target_attributes.gen.go", + subtypeName: "TcpTarget", + parentTypeName: "Target", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { - inProto: &targets.SshTargetAttributes{}, - outFile: "targets/ssh_target_attributes.gen.go", - subtypeName: "SshTarget", + inProto: &targets.SshTargetAttributes{}, + outFile: "targets/ssh_target_attributes.gen.go", + subtypeName: "SshTarget", + parentTypeName: "Target", + templates: []*template.Template{ + mapstructureConversionTemplate, + }, }, { inProto: &targets.Target{}, diff --git a/internal/api/genapi/templates.go b/internal/api/genapi/templates.go index 189d79eeb..e9b4c5282 100644 --- a/internal/api/genapi/templates.go +++ b/internal/api/genapi/templates.go @@ -792,6 +792,38 @@ func Default{{ $subtypeName }}{{ $field.Name }}() Option { {{ end }} `)) +var mapstructureConversionTemplate = template.Must(template.New("").Funcs( + template.FuncMap{ + "typeFromSubtype": typeFromSubtype, + "kebabCase": kebabCase, + }, +).Parse(` +func AttributesMapTo{{ .Name }}(in map[string]interface{}) (*{{ .Name }}, error) { + if in == nil { + return nil, fmt.Errorf("nil input map") + } + var out {{ .Name }} + 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 *{{ .ParentTypeName }}) Get{{ .Name }}() (*{{ .Name }}, error) { + if pt.Type != "{{ typeFromSubtype .Name .ParentTypeName "Attributes"}}" { + return nil, fmt.Errorf("asked to fetch %s-type attributes but {{ kebabCase .ParentTypeName }} is of type %s", "{{ typeFromSubtype .Name .ParentTypeName "Attributes"}}", pt.Type) + } + return AttributesMapTo{{ .Name }}(pt.Attributes) +} +`)) + func makeSlice(strs ...string) []string { return strs } @@ -829,3 +861,7 @@ func removeDups(in []string) []string { return ret } + +func typeFromSubtype(in, parent, extraSuffix string) string { + return strings.ToLower(strings.TrimSuffix(strings.TrimSuffix(in, extraSuffix), parent)) +}