From aa7f304bc1db44463d76a5e2581c2ffd9b4d2cde Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Thu, 3 Nov 2016 14:32:23 -0700 Subject: [PATCH] *: switch to github.com/ghodss/yaml for more consistent YAML parsing ghodss/yaml converts from YAML to JSON before attempting to unmarshal. This allows us to: * Get the correct behavor when decoding base64'd []byte slices. * Use *json.RawMessage. * Not have to support extravagant YAML features. * Let our structs use `json:` tags --- TODO.md | 1 - cmd/dex/config.go | 250 +++++++++++----------------- cmd/dex/serve.go | 10 +- connector/github/github.go | 8 +- connector/ldap/ldap.go | 40 ++--- connector/mock/connectortest.go | 4 +- connector/oidc/oidc.go | 10 +- glide.lock | 6 +- storage/kubernetes/client.go | 2 +- storage/kubernetes/k8sapi/client.go | 78 ++++----- storage/kubernetes/storage.go | 4 +- storage/sql/config.go | 2 +- storage/storage.go | 8 +- 13 files changed, 185 insertions(+), 238 deletions(-) diff --git a/TODO.md b/TODO.md index 03e9bc52..e67bea30 100644 --- a/TODO.md +++ b/TODO.md @@ -48,4 +48,3 @@ Backend - [ ] Improve logging, possibly switch to logrus - [ ] Standardize OAuth2 error handling -- [ ] Switch to github.com/ghodss/yaml for []byte to base64 string logic diff --git a/cmd/dex/config.go b/cmd/dex/config.go index 69b4f12c..26c82311 100644 --- a/cmd/dex/config.go +++ b/cmd/dex/config.go @@ -1,7 +1,7 @@ package main import ( - "encoding/base64" + "encoding/json" "fmt" "github.com/coreos/dex/connector" @@ -18,129 +18,58 @@ import ( // Config is the config format for the main application. type Config struct { - Issuer string `yaml:"issuer"` - Storage Storage `yaml:"storage"` - Connectors []Connector `yaml:"connectors"` - Web Web `yaml:"web"` - OAuth2 OAuth2 `yaml:"oauth2"` - GRPC GRPC `yaml:"grpc"` + Issuer string `json:"issuer"` + Storage Storage `json:"storage"` + Connectors []Connector `json:"connectors"` + Web Web `json:"web"` + OAuth2 OAuth2 `json:"oauth2"` + GRPC GRPC `json:"grpc"` - Templates server.TemplateConfig `yaml:"templates"` + Templates server.TemplateConfig `json:"templates"` // StaticClients cause the server to use this list of clients rather than // querying the storage. Write operations, like creating a client, will fail. - StaticClients []storage.Client `yaml:"staticClients"` + StaticClients []storage.Client `json:"staticClients"` // If enabled, the server will maintain a list of passwords which can be used // to identify a user. - EnablePasswordDB bool `yaml:"enablePasswordDB"` + EnablePasswordDB bool `json:"enablePasswordDB"` // StaticPasswords cause the server use this list of passwords rather than // querying the storage. Cannot be specified without enabling a passwords // database. - // - // The "password" type is identical to the storage.Password type, but does - // unmarshaling into []byte correctly. - StaticPasswords []password `yaml:"staticPasswords"` -} - -type password struct { - Email string `yaml:"email"` - Username string `yaml:"username"` - UserID string `yaml:"userID"` - - // Because our YAML parser doesn't base64, we have to do it ourselves. - // - // TODO(ericchiang): switch to github.com/ghodss/yaml - Hash string `yaml:"hash"` -} - -// decode the hash appropriately and convert to the storage passwords. -func (p password) toPassword() (storage.Password, error) { - hash, err := base64.StdEncoding.DecodeString(p.Hash) - if err != nil { - return storage.Password{}, fmt.Errorf("decoding hash: %v", err) - } - return storage.Password{ - Email: p.Email, - Username: p.Username, - UserID: p.UserID, - Hash: hash, - }, nil + StaticPasswords []storage.Password `json:"staticPasswords"` } // OAuth2 describes enabled OAuth2 extensions. type OAuth2 struct { - ResponseTypes []string `yaml:"responseTypes"` + ResponseTypes []string `json:"responseTypes"` // If specified, do not prompt the user to approve client authorization. The // act of logging in implies authorization. - SkipApprovalScreen bool `yaml:"skipApprovalScreen"` + SkipApprovalScreen bool `json:"skipApprovalScreen"` } // Web is the config format for the HTTP server. type Web struct { - HTTP string `yaml:"http"` - HTTPS string `yaml:"https"` - TLSCert string `yaml:"tlsCert"` - TLSKey string `yaml:"tlsKey"` + HTTP string `json:"http"` + HTTPS string `json:"https"` + TLSCert string `json:"tlsCert"` + TLSKey string `json:"tlsKey"` } // GRPC is the config for the gRPC API. type GRPC struct { // The port to listen on. - Addr string `yaml:"addr"` - TLSCert string `yaml:"tlsCert"` - TLSKey string `yaml:"tlsKey"` - TLSClientCA string `yaml:"tlsClientCA"` + Addr string `json:"addr"` + TLSCert string `json:"tlsCert"` + TLSKey string `json:"tlsKey"` + TLSClientCA string `json:"tlsClientCA"` } // Storage holds app's storage configuration. type Storage struct { - Type string `yaml:"type"` - Config StorageConfig `yaml:"config"` -} - -// UnmarshalYAML allows Storage to unmarshal its config field dynamically -// depending on the type of storage. -func (s *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error { - var storageMeta struct { - Type string `yaml:"type"` - } - if err := unmarshal(&storageMeta); err != nil { - return err - } - s.Type = storageMeta.Type - // TODO(ericchiang): replace this with a registration process. - var err error - switch storageMeta.Type { - case "kubernetes": - var config struct { - Config kubernetes.Config `yaml:"config"` - } - err = unmarshal(&config) - s.Config = &config.Config - case "memory": - var config struct { - Config memory.Config `yaml:"config"` - } - err = unmarshal(&config) - s.Config = &config.Config - case "sqlite3": - var config struct { - Config sql.SQLite3 `yaml:"config"` - } - err = unmarshal(&config) - s.Config = &config.Config - case "postgres": - var config struct { - Config sql.Postgres `yaml:"config"` - } - err = unmarshal(&config) - s.Config = &config.Config - default: - return fmt.Errorf("unknown storage type %q", storageMeta.Type) - } - return err + Type string `json:"type"` + Config StorageConfig `json:"config"` } // StorageConfig is a configuration that can create a storage. @@ -148,14 +77,49 @@ type StorageConfig interface { Open() (storage.Storage, error) } +var storages = map[string]func() StorageConfig{ + "kubernetes": func() StorageConfig { return new(kubernetes.Config) }, + "memory": func() StorageConfig { return new(memory.Config) }, + "sqlite3": func() StorageConfig { return new(sql.SQLite3) }, + "postgres": func() StorageConfig { return new(sql.Postgres) }, +} + +// UnmarshalJSON allows Storage to implement the unmarshaler interface to +// dynamically determine the type of the storage config. +func (s *Storage) UnmarshalJSON(b []byte) error { + var store struct { + Type string `json:"type"` + Config json.RawMessage `json:"config"` + } + if err := json.Unmarshal(b, &store); err != nil { + return fmt.Errorf("parse storage: %v", err) + } + f, ok := storages[store.Type] + if !ok { + return fmt.Errorf("unknown storage type %q", store.Type) + } + + storageConfig := f() + if len(store.Config) != 0 { + if err := json.Unmarshal([]byte(store.Config), storageConfig); err != nil { + return fmt.Errorf("parse storace config: %v", err) + } + } + *s = Storage{ + Type: store.Type, + Config: storageConfig, + } + return nil +} + // Connector is a magical type that can unmarshal YAML dynamically. The // Type field determines the connector type, which is then customized for Config. type Connector struct { - Type string `yaml:"type"` - Name string `yaml:"name"` - ID string `yaml:"id"` + Type string `json:"type"` + Name string `json:"name"` + ID string `json:"id"` - Config ConnectorConfig `yaml:"config"` + Config ConnectorConfig `json:"config"` } // ConnectorConfig is a configuration that can open a connector. @@ -163,55 +127,43 @@ type ConnectorConfig interface { Open() (connector.Connector, error) } -// UnmarshalYAML allows Connector to unmarshal its config field dynamically -// depending on the type of connector. -func (c *Connector) UnmarshalYAML(unmarshal func(interface{}) error) error { - var connectorMetadata struct { - Type string `yaml:"type"` - Name string `yaml:"name"` - ID string `yaml:"id"` - } - if err := unmarshal(&connectorMetadata); err != nil { - return err - } - c.Type = connectorMetadata.Type - c.Name = connectorMetadata.Name - c.ID = connectorMetadata.ID - - var err error - switch c.Type { - case "mockCallback": - var config struct { - Config mock.CallbackConfig `yaml:"config"` - } - err = unmarshal(&config) - c.Config = &config.Config - case "mockPassword": - var config struct { - Config mock.PasswordConfig `yaml:"config"` - } - err = unmarshal(&config) - c.Config = &config.Config - case "ldap": - var config struct { - Config ldap.Config `yaml:"config"` - } - err = unmarshal(&config) - c.Config = &config.Config - case "github": - var config struct { - Config github.Config `yaml:"config"` - } - err = unmarshal(&config) - c.Config = &config.Config - case "oidc": - var config struct { - Config oidc.Config `yaml:"config"` - } - err = unmarshal(&config) - c.Config = &config.Config - default: - return fmt.Errorf("unknown connector type %q", c.Type) - } - return err +var connectors = map[string]func() ConnectorConfig{ + "mockCallback": func() ConnectorConfig { return new(mock.CallbackConfig) }, + "mockPassword": func() ConnectorConfig { return new(mock.PasswordConfig) }, + "ldap": func() ConnectorConfig { return new(ldap.Config) }, + "github": func() ConnectorConfig { return new(github.Config) }, + "oidc": func() ConnectorConfig { return new(oidc.Config) }, +} + +// UnmarshalJSON allows Connector to implement the unmarshaler interface to +// dynamically determine the type of the connector config. +func (c *Connector) UnmarshalJSON(b []byte) error { + var conn struct { + Type string `json:"type"` + Name string `json:"name"` + ID string `json:"id"` + + Config json.RawMessage `json:"config"` + } + if err := json.Unmarshal(b, &conn); err != nil { + return fmt.Errorf("parse connector: %v", err) + } + f, ok := connectors[conn.Type] + if !ok { + return fmt.Errorf("unknown connector type %q", conn.Type) + } + + connConfig := f() + if len(conn.Config) != 0 { + if err := json.Unmarshal([]byte(conn.Config), connConfig); err != nil { + return fmt.Errorf("parse connector config: %v", err) + } + } + *c = Connector{ + Type: conn.Type, + Name: conn.Type, + ID: conn.ID, + Config: connConfig, + } + return nil } diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go index 489a20c0..d6d545e7 100644 --- a/cmd/dex/serve.go +++ b/cmd/dex/serve.go @@ -11,11 +11,11 @@ import ( "net/http" "os" + "github.com/ghodss/yaml" "github.com/spf13/cobra" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" - yaml "gopkg.in/yaml.v2" "github.com/coreos/dex/api" "github.com/coreos/dex/server" @@ -136,13 +136,7 @@ func serve(cmd *cobra.Command, args []string) error { s = storage.WithStaticClients(s, c.StaticClients) } if len(c.StaticPasswords) > 0 { - p := make([]storage.Password, len(c.StaticPasswords)) - for i, pw := range c.StaticPasswords { - if p[i], err = pw.toPassword(); err != nil { - return err - } - } - s = storage.WithStaticPasswords(s, p) + s = storage.WithStaticPasswords(s, c.StaticPasswords) } serverConfig := server.Config{ diff --git a/connector/github/github.go b/connector/github/github.go index ab22217b..9e14f60f 100644 --- a/connector/github/github.go +++ b/connector/github/github.go @@ -19,10 +19,10 @@ const baseURL = "https://api.github.com" // Config holds configuration options for github logins. type Config struct { - ClientID string `yaml:"clientID"` - ClientSecret string `yaml:"clientSecret"` - RedirectURI string `yaml:"redirectURI"` - Org string `yaml:"org"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + RedirectURI string `json:"redirectURI"` + Org string `json:"org"` } // Open returns a strategy for logging in through GitHub. diff --git a/connector/ldap/ldap.go b/connector/ldap/ldap.go index 841ff110..dd45dd10 100644 --- a/connector/ldap/ldap.go +++ b/connector/ldap/ldap.go @@ -53,52 +53,52 @@ import ( type Config struct { // The host and optional port of the LDAP server. If port isn't supplied, it will be // guessed based on the TLS configuration. 389 or 636. - Host string `yaml:"host"` + Host string `json:"host"` // Required if LDAP host does not use TLS. - InsecureNoSSL bool `yaml:"insecureNoSSL"` + InsecureNoSSL bool `json:"insecureNoSSL"` // Path to a trusted root certificate file. - RootCA string `yaml:"rootCA"` + RootCA string `json:"rootCA"` // BindDN and BindPW for an application service account. The connector uses these // credentials to search for users and groups. - BindDN string `yaml:"bindDN"` - BindPW string `yaml:"bindPW"` + BindDN string `json:"bindDN"` + BindPW string `json:"bindPW"` // User entry search configuration. UserSearch struct { // BsaeDN to start the search from. For example "cn=users,dc=example,dc=com" - BaseDN string `yaml:"baseDN"` + BaseDN string `json:"baseDN"` // Optional filter to apply when searching the directory. For example "(objectClass=person)" - Filter string `yaml:"filter"` + Filter string `json:"filter"` // Attribute to match against the inputted username. This will be translated and combined // with the other filter as "(=)". - Username string `yaml:"username"` + Username string `json:"username"` // Can either be: // * "sub" - search the whole sub tree // * "one" - only search one level - Scope string `yaml:"scope"` + Scope string `json:"scope"` // A mapping of attributes on the user entry to claims. - IDAttr string `yaml:"idAttr"` // Defaults to "uid" - EmailAttr string `yaml:"emailAttr"` // Defaults to "mail" - NameAttr string `yaml:"nameAttr"` // No default. + IDAttr string `json:"idAttr"` // Defaults to "uid" + EmailAttr string `json:"emailAttr"` // Defaults to "mail" + NameAttr string `json:"nameAttr"` // No default. - } `yaml:"userSearch"` + } `json:"userSearch"` // Group search configuration. GroupSearch struct { // BsaeDN to start the search from. For example "cn=groups,dc=example,dc=com" - BaseDN string `yaml:"baseDN"` + BaseDN string `json:"baseDN"` // Optional filter to apply when searching the directory. For example "(objectClass=posixGroup)" - Filter string `yaml:"filter"` + Filter string `json:"filter"` - Scope string `yaml:"scope"` // Defaults to "sub" + Scope string `json:"scope"` // Defaults to "sub" // These two fields are use to match a user to a group. // @@ -108,12 +108,12 @@ type Config struct { // // (=) // - UserAttr string `yaml:"userAttr"` - GroupAttr string `yaml:"groupAttr"` + UserAttr string `json:"userAttr"` + GroupAttr string `json:"groupAttr"` // The attribute of the group that represents its name. - NameAttr string `yaml:"nameAttr"` - } `yaml:"groupSearch"` + NameAttr string `json:"nameAttr"` + } `json:"groupSearch"` } func parseScope(s string) (int, bool) { diff --git a/connector/mock/connectortest.go b/connector/mock/connectortest.go index 1ceeb361..58b3e10b 100644 --- a/connector/mock/connectortest.go +++ b/connector/mock/connectortest.go @@ -69,8 +69,8 @@ func (c *CallbackConfig) Open() (connector.Connector, error) { // PasswordConfig holds the configuration for a mock connector which prompts for the supplied // username and password. type PasswordConfig struct { - Username string `yaml:"username"` - Password string `yaml:"password"` + Username string `json:"username"` + Password string `json:"password"` } // Open returns an authentication strategy which prompts for a predefined username and password. diff --git a/connector/oidc/oidc.go b/connector/oidc/oidc.go index 9b5aad20..cd9656f1 100644 --- a/connector/oidc/oidc.go +++ b/connector/oidc/oidc.go @@ -15,12 +15,12 @@ import ( // Config holds configuration options for OpenID Connect logins. type Config struct { - Issuer string `yaml:"issuer"` - ClientID string `yaml:"clientID"` - ClientSecret string `yaml:"clientSecret"` - RedirectURI string `yaml:"redirectURI"` + Issuer string `json:"issuer"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + RedirectURI string `json:"redirectURI"` - Scopes []string `yaml:"scopes"` // defaults to "profile" and "email" + Scopes []string `json:"scopes"` // defaults to "profile" and "email" } // Open returns a connector which can be used to login users through an upstream diff --git a/glide.lock b/glide.lock index c743fb33..41f250fa 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: a813cbca07393d7cbe35d411cdef588afac7a3bab8a287ffe7b9587516ef5898 -updated: 2016-10-23T20:51:55.313818678-07:00 +hash: bc7fa6bbfddcb39710064a9d6dab090d49bd88486571cae12c68c4b70093e716 +updated: 2016-11-03T14:31:37.323302694-07:00 imports: - name: github.com/cockroachdb/cockroach-go version: 31611c0501c812f437d4861d87d117053967c955 @@ -7,6 +7,8 @@ imports: - crdb - name: github.com/ericchiang/oidc version: 1907f0e61549f9081f26bdf269f11603496c9dee +- name: github.com/ghodss/yaml + version: bea76d6a4713e18b7f5321a2b020738552def3ea - name: github.com/go-sql-driver/mysql version: 0b58b37b664c21f3010e836f1b931e1d0b0b0685 - name: github.com/golang/protobuf diff --git a/storage/kubernetes/client.go b/storage/kubernetes/client.go index dfb1fe35..99fefa82 100644 --- a/storage/kubernetes/client.go +++ b/storage/kubernetes/client.go @@ -21,9 +21,9 @@ import ( "strings" "time" + "github.com/ghodss/yaml" "github.com/gtank/cryptopasta" "golang.org/x/net/context" - yaml "gopkg.in/yaml.v2" "github.com/coreos/dex/storage" "github.com/coreos/dex/storage/kubernetes/k8sapi" diff --git a/storage/kubernetes/k8sapi/client.go b/storage/kubernetes/k8sapi/client.go index d84fa5cc..4e71dd07 100644 --- a/storage/kubernetes/k8sapi/client.go +++ b/storage/kubernetes/k8sapi/client.go @@ -23,124 +23,124 @@ package k8sapi type Config struct { // Legacy field from pkg/api/types.go TypeMeta. // TODO(jlowdermilk): remove this after eliminating downstream dependencies. - Kind string `yaml:"kind,omitempty"` + Kind string `json:"kind,omitempty"` // DEPRECATED: APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc). // Because a cluster can run multiple API groups and potentially multiple versions of each, it no longer makes sense to specify // a single value for the cluster version. // This field isn't really needed anyway, so we are deprecating it without replacement. // It will be ignored if it is present. - APIVersion string `yaml:"apiVersion,omitempty"` + APIVersion string `json:"apiVersion,omitempty"` // Preferences holds general information to be use for cli interactions - Preferences Preferences `yaml:"preferences"` + Preferences Preferences `json:"preferences"` // Clusters is a map of referencable names to cluster configs - Clusters []NamedCluster `yaml:"clusters"` + Clusters []NamedCluster `json:"clusters"` // AuthInfos is a map of referencable names to user configs - AuthInfos []NamedAuthInfo `yaml:"users"` + AuthInfos []NamedAuthInfo `json:"users"` // Contexts is a map of referencable names to context configs - Contexts []NamedContext `yaml:"contexts"` + Contexts []NamedContext `json:"contexts"` // CurrentContext is the name of the context that you would like to use by default - CurrentContext string `yaml:"current-context"` + CurrentContext string `json:"current-context"` // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields - Extensions []NamedExtension `yaml:"extensions,omitempty"` + Extensions []NamedExtension `json:"extensions,omitempty"` } // Preferences contains information about the users command line experience preferences. type Preferences struct { - Colors bool `yaml:"colors,omitempty"` + Colors bool `json:"colors,omitempty"` // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields - Extensions []NamedExtension `yaml:"extensions,omitempty"` + Extensions []NamedExtension `json:"extensions,omitempty"` } // Cluster contains information about how to communicate with a kubernetes cluster type Cluster struct { // Server is the address of the kubernetes cluster (https://hostname:port). - Server string `yaml:"server"` + Server string `json:"server"` // APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc). - APIVersion string `yaml:"api-version,omitempty"` + APIVersion string `json:"api-version,omitempty"` // InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure. - InsecureSkipTLSVerify bool `yaml:"insecure-skip-tls-verify,omitempty"` + InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"` // CertificateAuthority is the path to a cert file for the certificate authority. - CertificateAuthority string `yaml:"certificate-authority,omitempty"` + CertificateAuthority string `json:"certificate-authority,omitempty"` // CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority // // NOTE(ericchiang): Our yaml parser doesn't assume []byte is a base64 encoded string. - CertificateAuthorityData string `yaml:"certificate-authority-data,omitempty"` + CertificateAuthorityData string `json:"certificate-authority-data,omitempty"` // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields - Extensions []NamedExtension `yaml:"extensions,omitempty"` + Extensions []NamedExtension `json:"extensions,omitempty"` } // AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are. type AuthInfo struct { // ClientCertificate is the path to a client cert file for TLS. - ClientCertificate string `yaml:"client-certificate,omitempty"` + ClientCertificate string `json:"client-certificate,omitempty"` // ClientCertificateData contains PEM-encoded data from a client cert file for TLS. Overrides ClientCertificate // // NOTE(ericchiang): Our yaml parser doesn't assume []byte is a base64 encoded string. - ClientCertificateData string `yaml:"client-certificate-data,omitempty"` + ClientCertificateData string `json:"client-certificate-data,omitempty"` // ClientKey is the path to a client key file for TLS. - ClientKey string `yaml:"client-key,omitempty"` + ClientKey string `json:"client-key,omitempty"` // ClientKeyData contains PEM-encoded data from a client key file for TLS. Overrides ClientKey // // NOTE(ericchiang): Our yaml parser doesn't assume []byte is a base64 encoded string. - ClientKeyData string `yaml:"client-key-data,omitempty"` + ClientKeyData string `json:"client-key-data,omitempty"` // Token is the bearer token for authentication to the kubernetes cluster. - Token string `yaml:"token,omitempty"` + Token string `json:"token,omitempty"` // Impersonate is the username to imperonate. The name matches the flag. - Impersonate string `yaml:"as,omitempty"` + Impersonate string `json:"as,omitempty"` // Username is the username for basic authentication to the kubernetes cluster. - Username string `yaml:"username,omitempty"` + Username string `json:"username,omitempty"` // Password is the password for basic authentication to the kubernetes cluster. - Password string `yaml:"password,omitempty"` + Password string `json:"password,omitempty"` // AuthProvider specifies a custom authentication plugin for the kubernetes cluster. - AuthProvider *AuthProviderConfig `yaml:"auth-provider,omitempty"` + AuthProvider *AuthProviderConfig `json:"auth-provider,omitempty"` // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields - Extensions []NamedExtension `yaml:"extensions,omitempty"` + Extensions []NamedExtension `json:"extensions,omitempty"` } // Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with) type Context struct { // Cluster is the name of the cluster for this context - Cluster string `yaml:"cluster"` + Cluster string `json:"cluster"` // AuthInfo is the name of the authInfo for this context - AuthInfo string `yaml:"user"` + AuthInfo string `json:"user"` // Namespace is the default namespace to use on unspecified requests - Namespace string `yaml:"namespace,omitempty"` + Namespace string `json:"namespace,omitempty"` // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields - Extensions []NamedExtension `yaml:"extensions,omitempty"` + Extensions []NamedExtension `json:"extensions,omitempty"` } // NamedCluster relates nicknames to cluster information type NamedCluster struct { // Name is the nickname for this Cluster - Name string `yaml:"name"` + Name string `json:"name"` // Cluster holds the cluster information - Cluster Cluster `yaml:"cluster"` + Cluster Cluster `json:"cluster"` } // NamedContext relates nicknames to context information type NamedContext struct { // Name is the nickname for this Context - Name string `yaml:"name"` + Name string `json:"name"` // Context holds the context information - Context Context `yaml:"context"` + Context Context `json:"context"` } // NamedAuthInfo relates nicknames to auth information type NamedAuthInfo struct { // Name is the nickname for this AuthInfo - Name string `yaml:"name"` + Name string `json:"name"` // AuthInfo holds the auth information - AuthInfo AuthInfo `yaml:"user"` + AuthInfo AuthInfo `json:"user"` } // NamedExtension relates nicknames to extension information type NamedExtension struct { // Name is the nickname for this Extension - Name string `yaml:"name"` + Name string `json:"name"` } // AuthProviderConfig holds the configuration for a specified auth provider. type AuthProviderConfig struct { - Name string `yaml:"name"` - Config map[string]string `yaml:"config"` + Name string `json:"name"` + Config map[string]string `json:"config"` } diff --git a/storage/kubernetes/storage.go b/storage/kubernetes/storage.go index 05e088d4..08df0161 100644 --- a/storage/kubernetes/storage.go +++ b/storage/kubernetes/storage.go @@ -34,8 +34,8 @@ const ( // Config values for the Kubernetes storage type. type Config struct { - InCluster bool `yaml:"inCluster"` - KubeConfigFile string `yaml:"kubeConfigFile"` + InCluster bool `json:"inCluster"` + KubeConfigFile string `json:"kubeConfigFile"` } // Open returns a storage using Kubernetes third party resource. diff --git a/storage/sql/config.go b/storage/sql/config.go index f8cdf248..071f0b03 100644 --- a/storage/sql/config.go +++ b/storage/sql/config.go @@ -12,7 +12,7 @@ import ( // SQLite3 options for creating an SQL db. type SQLite3 struct { // File to - File string `yaml:"file"` + File string `json:"file"` } // Open creates a new storage implementation backed by SQLite3 diff --git a/storage/storage.go b/storage/storage.go index addec4ae..0d5b1f7f 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -247,16 +247,16 @@ type Password struct { // // Storages that don't support an extended character set for IDs, such as '.' and '@' // (cough cough, kubernetes), must map this value appropriately. - Email string `yaml:"email"` + Email string `json:"email"` // Bcrypt encoded hash of the password. This package enforces a min cost value of 10 - Hash []byte `yaml:"hash"` + Hash []byte `json:"hash"` // Optional username to display. NOT used during login. - Username string `yaml:"username"` + Username string `json:"username"` // Randomly generated user ID. This is NOT the primary ID of the Password object. - UserID string `yaml:"userID"` + UserID string `json:"userID"` } // VerificationKey is a rotated signing key which can still be used to verify