// clientauth.Info object contain both user identification and server identification. We want different precedence orders for // both, so we have to split the objects and merge them separately // we want this order of precedence for user identifcation // 1. configAuthInfo minus auth-path (the final result of command line flags and merged .kubeconfig files) // 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority) // 3. if there is not enough information to idenfity the user, load try the ~/.kubernetes_auth file // 4. if there is not enough information to identify the user, prompt if possible func getUserIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, fallbackReader io.Reader) (*client.Config, error) { mergedConfig := &client.Config{} // blindly overwrite existing values based on precedence if len(configAuthInfo.Token) > 0 { mergedConfig.BearerToken = configAuthInfo.Token } if len(configAuthInfo.ClientCertificate) > 0 || len(configAuthInfo.ClientCertificateData) > 0 { mergedConfig.CertFile = configAuthInfo.ClientCertificate mergedConfig.CertData = configAuthInfo.ClientCertificateData mergedConfig.KeyFile = configAuthInfo.ClientKey mergedConfig.KeyData = configAuthInfo.ClientKeyData } if len(configAuthInfo.Username) > 0 || len(configAuthInfo.Password) > 0 { mergedConfig.Username = configAuthInfo.Username mergedConfig.Password = configAuthInfo.Password } // if there still isn't enough information to authenticate the user, try prompting if !canIdentifyUser(*mergedConfig) && (fallbackReader != nil) { prompter := NewPromptingAuthLoader(fallbackReader) promptedAuthInfo := prompter.Prompt() promptedConfig := makeUserIdentificationConfig(*promptedAuthInfo) previouslyMergedConfig := mergedConfig mergedConfig = &client.Config{} mergo.Merge(mergedConfig, promptedConfig) mergo.Merge(mergedConfig, previouslyMergedConfig) } return mergedConfig, nil }
// clientauth.Info object contain both user identification and server identification. We want different precedence orders for // both, so we have to split the objects and merge them separately // we want this order of precedence for the server identification // 1. configClusterInfo (the final result of command line flags and merged .kubeconfig files) // 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority) // 3. load the ~/.kubernetes_auth file as a default func getServerIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, configClusterInfo clientcmdapi.Cluster) (*client.Config, error) { mergedConfig := &client.Config{} defaultAuthPathInfo, err := NewDefaultAuthLoader().LoadAuth(os.Getenv("HOME") + "/.kubernetes_auth") // if the error is anything besides a does not exist, then fail. Not existing is ok if err != nil && !os.IsNotExist(err) { return nil, err } if defaultAuthPathInfo != nil { defaultAuthPathConfig := makeServerIdentificationConfig(*defaultAuthPathInfo) mergo.Merge(mergedConfig, defaultAuthPathConfig) } if len(configAuthInfo.AuthPath) > 0 { authPathInfo, err := NewDefaultAuthLoader().LoadAuth(configAuthInfo.AuthPath) if err != nil { return nil, err } authPathConfig := makeServerIdentificationConfig(*authPathInfo) mergo.Merge(mergedConfig, authPathConfig) } // configClusterInfo holds the information identify the server provided by .kubeconfig configClientConfig := &client.Config{} configClientConfig.CAFile = configClusterInfo.CertificateAuthority configClientConfig.CAData = configClusterInfo.CertificateAuthorityData configClientConfig.Insecure = configClusterInfo.InsecureSkipTLSVerify mergo.Merge(mergedConfig, configClientConfig) return mergedConfig, nil }
func loadConfigFile(o *Options) { isDefault := false configPath := o.ConfigFile if o.ConfigFile == "" { isDefault = true configPath = "./deploy.yaml" } data, err := ioutil.ReadFile(configPath) if err != nil { if os.IsNotExist(err) && isDefault { return } panic(err) } var file ConfigFile err = yaml.Unmarshal(data, &file) panicIf(err) var envCfg Options if o.Env != "" { var ok bool envCfg, ok = file[o.Env] if !ok { panic("Config for specified env not found") } } defCfg, _ := file["default"] panicIf(mergo.Merge(o, defCfg)) panicIf(mergo.Merge(o, envCfg)) }
// ClientConfig implements ClientConfig func (config DirectClientConfig) ClientConfig() (*client.Config, error) { if err := config.ConfirmUsable(); err != nil { return nil, err } configAuthInfo := config.getAuthInfo() configClusterInfo := config.getCluster() clientConfig := &client.Config{} clientConfig.Host = configClusterInfo.Server clientConfig.Version = configClusterInfo.APIVersion // only try to read the auth information if we are secure if client.IsConfigTransportTLS(*clientConfig) { var err error // mergo is a first write wins for map value and a last writing wins for interface values userAuthPartialConfig, err := getUserIdentificationPartialConfig(configAuthInfo, config.fallbackReader) if err != nil { return nil, err } mergo.Merge(clientConfig, userAuthPartialConfig) serverAuthPartialConfig, err := getServerIdentificationPartialConfig(configAuthInfo, configClusterInfo) if err != nil { return nil, err } mergo.Merge(clientConfig, serverAuthPartialConfig) } return clientConfig, nil }
// clientauth.Info object contain both user identification and server identification. We want different precedence orders for // both, so we have to split the objects and merge them separately // we want this order of precedence for user identifcation // 1. configAuthInfo minus auth-path (the final result of command line flags and merged .kubeconfig files) // 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority) // 3. if there is not enough information to idenfity the user, load try the ~/.kubernetes_auth file // 4. if there is not enough information to identify the user, prompt if possible func getUserIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, fallbackReader io.Reader) (*client.Config, error) { mergedConfig := &client.Config{} if len(configAuthInfo.AuthPath) > 0 { authPathInfo, err := NewDefaultAuthLoader().LoadAuth(configAuthInfo.AuthPath) if err != nil { return nil, err } authPathConfig := makeUserIdentificationConfig(*authPathInfo) mergo.Merge(mergedConfig, authPathConfig) } // blindly overwrite existing values based on precedence if len(configAuthInfo.Token) > 0 { mergedConfig.BearerToken = configAuthInfo.Token } if len(configAuthInfo.ClientCertificate) > 0 || len(configAuthInfo.ClientCertificateData) > 0 { mergedConfig.CertFile = configAuthInfo.ClientCertificate mergedConfig.CertData = configAuthInfo.ClientCertificateData mergedConfig.KeyFile = configAuthInfo.ClientKey mergedConfig.KeyData = configAuthInfo.ClientKeyData } if len(configAuthInfo.Username) > 0 || len(configAuthInfo.Password) > 0 { mergedConfig.Username = configAuthInfo.Username mergedConfig.Password = configAuthInfo.Password } // if there isn't sufficient information to authenticate the user to the server, merge in ~/.kubernetes_auth. if !canIdentifyUser(*mergedConfig) { defaultAuthPathInfo, err := NewDefaultAuthLoader().LoadAuth(os.Getenv("HOME") + "/.kubernetes_auth") // if the error is anything besides a does not exist, then fail. Not existing is ok if err != nil && !os.IsNotExist(err) { return nil, err } if defaultAuthPathInfo != nil { defaultAuthPathConfig := makeUserIdentificationConfig(*defaultAuthPathInfo) previouslyMergedConfig := mergedConfig mergedConfig = &client.Config{} mergo.Merge(mergedConfig, defaultAuthPathConfig) mergo.Merge(mergedConfig, previouslyMergedConfig) } } // if there still isn't enough information to authenticate the user, try prompting if !canIdentifyUser(*mergedConfig) && (fallbackReader != nil) { prompter := NewPromptingAuthLoader(fallbackReader) promptedAuthInfo := prompter.Prompt() promptedConfig := makeUserIdentificationConfig(*promptedAuthInfo) previouslyMergedConfig := mergedConfig mergedConfig = &client.Config{} mergo.Merge(mergedConfig, promptedConfig) mergo.Merge(mergedConfig, previouslyMergedConfig) } return mergedConfig, nil }
// ClientConfig implements ClientConfig func (config *DirectClientConfig) ClientConfig() (*rest.Config, error) { if err := config.ConfirmUsable(); err != nil { return nil, err } configAuthInfo := config.getAuthInfo() configClusterInfo := config.getCluster() clientConfig := &rest.Config{} clientConfig.Host = configClusterInfo.Server if len(config.overrides.Timeout) > 0 { if i, err := strconv.ParseInt(config.overrides.Timeout, 10, 64); err == nil && i >= 0 { clientConfig.Timeout = time.Duration(i) * time.Second } else if requestTimeout, err := time.ParseDuration(config.overrides.Timeout); err == nil { clientConfig.Timeout = requestTimeout } else { return nil, fmt.Errorf("Invalid value for option '--request-timeout'. Value must be a single integer, or an integer followed by a corresponding time unit (e.g. 1s | 2m | 3h)") } } if u, err := url.ParseRequestURI(clientConfig.Host); err == nil && u.Opaque == "" && len(u.Path) > 1 { u.RawQuery = "" u.Fragment = "" clientConfig.Host = u.String() } if len(configAuthInfo.Impersonate) > 0 { clientConfig.Impersonate = configAuthInfo.Impersonate } // only try to read the auth information if we are secure if rest.IsConfigTransportTLS(*clientConfig) { var err error // mergo is a first write wins for map value and a last writing wins for interface values // NOTE: This behavior changed with https://github.com/imdario/mergo/commit/d304790b2ed594794496464fadd89d2bb266600a. // Our mergo.Merge version is older than this change. var persister rest.AuthProviderConfigPersister if config.configAccess != nil { persister = PersisterForUser(config.configAccess, config.getAuthInfoName()) } userAuthPartialConfig, err := getUserIdentificationPartialConfig(configAuthInfo, config.fallbackReader, persister) if err != nil { return nil, err } mergo.Merge(clientConfig, userAuthPartialConfig) serverAuthPartialConfig, err := getServerIdentificationPartialConfig(configAuthInfo, configClusterInfo) if err != nil { return nil, err } mergo.Merge(clientConfig, serverAuthPartialConfig) } return clientConfig, nil }
// Load is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd.ClientConfigLoadingRules.Load // Load starts by running the MigrationRules and then // takes the loading rules and returns a Config object based on following rules. // if the ExplicitPath, return the unmerged explicit file // Otherwise, return a merged config based on the Precedence slice // A missing ExplicitPath file produces an error. Empty filenames or other missing files are ignored. // Read errors or files with non-deserializable content produce errors. // The first file to set a particular map key wins and map key's value is never changed. // BUT, if you set a struct value that is NOT contained inside of map, the value WILL be changed. // This results in some odd looking logic to merge in one direction, merge in the other, and then merge the two. // It also means that if two files specify a "red-user", only values from the first file's red-user are used. Even // non-conflicting entries from the second file's "red-user" are discarded. // Relative paths inside of the .kubeconfig files are resolved against the .kubeconfig file's parent folder // and only absolute file paths are returned. func (rules *clientConfigLoadingRules) Load() (*clientcmdConfig, error) { errlist := []error{} kubeConfigFiles := []string{} // REMOVED: explicit path support kubeConfigFiles = append(kubeConfigFiles, rules.Precedence...) kubeconfigs := []*clientcmdConfig{} // read and cache the config files so that we only look at them once for _, filename := range kubeConfigFiles { if len(filename) == 0 { // no work to do continue } config, err := loadFromFile(filename) if os.IsNotExist(err) { // skip missing files continue } if err != nil { errlist = append(errlist, fmt.Errorf("Error loading config file \"%s\": %v", filename, err)) continue } kubeconfigs = append(kubeconfigs, config) } // first merge all of our maps mapConfig := clientcmdNewConfig() for _, kubeconfig := range kubeconfigs { mergo.Merge(mapConfig, kubeconfig) } // merge all of the struct values in the reverse order so that priority is given correctly // errors are not added to the list the second time nonMapConfig := clientcmdNewConfig() for i := len(kubeconfigs) - 1; i >= 0; i-- { kubeconfig := kubeconfigs[i] mergo.Merge(nonMapConfig, kubeconfig) } // since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and // get the values we expect. config := clientcmdNewConfig() mergo.Merge(config, mapConfig) mergo.Merge(config, nonMapConfig) // REMOVED: Possibility to skip this. if err := resolveLocalPaths(config); err != nil { errlist = append(errlist, err) } return config, utilerrors.NewAggregate(errlist) }
// clientauth.Info object contain both user identification and server identification. We want different precedence orders for // both, so we have to split the objects and merge them separately // we want this order of precedence for user identifcation // 1. configAuthInfo minus auth-path (the final result of command line flags and merged .kubeconfig files) // 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority) // 3. if there is not enough information to idenfity the user, load try the ~/.kubernetes_auth file // 4. if there is not enough information to identify the user, prompt if possible func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, fallbackReader io.Reader, persistAuthConfig rest.AuthProviderConfigPersister) (*rest.Config, error) { mergedConfig := &rest.Config{} // blindly overwrite existing values based on precedence if len(configAuthInfo.Token) > 0 { mergedConfig.BearerToken = configAuthInfo.Token } else if len(configAuthInfo.TokenFile) > 0 { tokenBytes, err := ioutil.ReadFile(configAuthInfo.TokenFile) if err != nil { return nil, err } mergedConfig.BearerToken = string(tokenBytes) } if len(configAuthInfo.Impersonate) > 0 { mergedConfig.Impersonate = rest.ImpersonationConfig{UserName: configAuthInfo.Impersonate} } if len(configAuthInfo.ClientCertificate) > 0 || len(configAuthInfo.ClientCertificateData) > 0 { mergedConfig.CertFile = configAuthInfo.ClientCertificate mergedConfig.CertData = configAuthInfo.ClientCertificateData mergedConfig.KeyFile = configAuthInfo.ClientKey mergedConfig.KeyData = configAuthInfo.ClientKeyData } if len(configAuthInfo.Username) > 0 || len(configAuthInfo.Password) > 0 { mergedConfig.Username = configAuthInfo.Username mergedConfig.Password = configAuthInfo.Password } if configAuthInfo.AuthProvider != nil { mergedConfig.AuthProvider = configAuthInfo.AuthProvider mergedConfig.AuthConfigPersister = persistAuthConfig } // if there still isn't enough information to authenticate the user, try prompting if !canIdentifyUser(*mergedConfig) && (fallbackReader != nil) { if len(config.promptedCredentials.username) > 0 && len(config.promptedCredentials.password) > 0 { mergedConfig.Username = config.promptedCredentials.username mergedConfig.Password = config.promptedCredentials.password return mergedConfig, nil } prompter := NewPromptingAuthLoader(fallbackReader) promptedAuthInfo, err := prompter.Prompt() if err != nil { return nil, err } promptedConfig := makeUserIdentificationConfig(*promptedAuthInfo) previouslyMergedConfig := mergedConfig mergedConfig = &rest.Config{} mergo.Merge(mergedConfig, promptedConfig) mergo.Merge(mergedConfig, previouslyMergedConfig) config.promptedCredentials.username = mergedConfig.Username config.promptedCredentials.password = mergedConfig.Password } return mergedConfig, nil }
func (config DirectClientConfig) getContext() clientcmdapi.Context { contexts := config.config.Contexts contextName := config.getContextName() var mergedContext clientcmdapi.Context if configContext, exists := contexts[contextName]; exists { mergo.Merge(&mergedContext, configContext) } mergo.Merge(&mergedContext, config.overrides.Context) return mergedContext }
func (config DirectClientConfig) getAuthInfo() clientcmdapi.AuthInfo { authInfos := config.config.AuthInfos authInfoName := config.getAuthInfoName() var mergedAuthInfo clientcmdapi.AuthInfo if configAuthInfo, exists := authInfos[authInfoName]; exists { mergo.Merge(&mergedAuthInfo, configAuthInfo) } mergo.Merge(&mergedAuthInfo, config.overrides.AuthInfo) return mergedAuthInfo }
// Load starts by running the MigrationRules and then // takes the loading rules and returns a Config object based on following rules. // if the ExplicitPath, return the unmerged explicit file // Otherwise, return a merged config based on the Precedence slice // A missing ExplicitPath file produces an error. Empty filenames or other missing files are ignored. // Read errors or files with non-deserializable content produce errors. // The first file to set a particular map key wins and map key's value is never changed. // BUT, if you set a struct value that is NOT contained inside of map, the value WILL be changed. // This results in some odd looking logic to merge in one direction, merge in the other, and then merge the two. // It also means that if two files specify a "red-user", only values from the first file's red-user are used. Even // non-conflicting entries from the second file's "red-user" are discarded. // Relative paths inside of the .kubeconfig files are resolved against the .kubeconfig file's parent folder // and only absolute file paths are returned. func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) { if err := rules.Migrate(); err != nil { return nil, err } errlist := []error{} kubeConfigFiles := []string{} // Make sure a file we were explicitly told to use exists if len(rules.ExplicitPath) > 0 { if _, err := os.Stat(rules.ExplicitPath); os.IsNotExist(err) { return nil, err } kubeConfigFiles = append(kubeConfigFiles, rules.ExplicitPath) } else { kubeConfigFiles = append(kubeConfigFiles, rules.Precedence...) } // first merge all of our maps mapConfig := clientcmdapi.NewConfig() for _, file := range kubeConfigFiles { if err := mergeConfigWithFile(mapConfig, file); err != nil { errlist = append(errlist, err) } if rules.ResolvePaths() { if err := ResolveLocalPaths(file, mapConfig); err != nil { errlist = append(errlist, err) } } } // merge all of the struct values in the reverse order so that priority is given correctly // errors are not added to the list the second time nonMapConfig := clientcmdapi.NewConfig() for i := len(kubeConfigFiles) - 1; i >= 0; i-- { file := kubeConfigFiles[i] mergeConfigWithFile(nonMapConfig, file) if rules.ResolvePaths() { ResolveLocalPaths(file, nonMapConfig) } } // since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and // get the values we expect. config := clientcmdapi.NewConfig() mergo.Merge(config, mapConfig) mergo.Merge(config, nonMapConfig) return config, errors.NewAggregate(errlist) }
// getAuthInfo returns the clientcmdapi.AuthInfo, or an error if a required auth info is not found. func (config *DirectClientConfig) getAuthInfo() (clientcmdapi.AuthInfo, error) { authInfos := config.config.AuthInfos authInfoName, required := config.getAuthInfoName() var mergedAuthInfo clientcmdapi.AuthInfo if configAuthInfo, exists := authInfos[authInfoName]; exists { mergo.Merge(&mergedAuthInfo, configAuthInfo) } else if required { return clientcmdapi.AuthInfo{}, fmt.Errorf("auth info %q does not exist", authInfoName) } mergo.Merge(&mergedAuthInfo, config.overrides.AuthInfo) return mergedAuthInfo, nil }
// getCluster is a modified copy of k8s.io/kubernetes/pkg/client/unversioned/clientcmd.DirectClientConfig.getCluster. func (config *directClientConfig) getCluster() clientcmdCluster { clusterInfos := config.config.Clusters clusterInfoName := config.getClusterName() var mergedClusterInfo clientcmdCluster mergo.Merge(&mergedClusterInfo, defaultCluster) mergo.Merge(&mergedClusterInfo, envVarCluster) if configClusterInfo, exists := clusterInfos[clusterInfoName]; exists { mergo.Merge(&mergedClusterInfo, configClusterInfo) } // REMOVED: overrides support return mergedClusterInfo }
func (config DirectClientConfig) getCluster() clientcmdapi.Cluster { clusterInfos := config.config.Clusters clusterInfoName := config.getClusterName() var mergedClusterInfo clientcmdapi.Cluster mergo.Merge(&mergedClusterInfo, DefaultCluster) mergo.Merge(&mergedClusterInfo, EnvVarCluster) if configClusterInfo, exists := clusterInfos[clusterInfoName]; exists { mergo.Merge(&mergedClusterInfo, configClusterInfo) } mergo.Merge(&mergedClusterInfo, config.overrides.ClusterInfo) return mergedClusterInfo }
// getContext returns the clientcmdapi.Context, or an error if a required context is not found. func (config *DirectClientConfig) getContext() (clientcmdapi.Context, error) { contexts := config.config.Contexts contextName, required := config.getContextName() var mergedContext clientcmdapi.Context if configContext, exists := contexts[contextName]; exists { mergo.Merge(&mergedContext, configContext) } else if required { return clientcmdapi.Context{}, fmt.Errorf("context %q does not exist", contextName) } mergo.Merge(&mergedContext, config.overrides.Context) return mergedContext, nil }
func createContext(envData *map[string]interface{}, provider *data.Provider, dataFile *string) (*pongo2.Context, error) { // Create context context := pongo2.Context{ "env": map[string]interface{}{ "provider": provider.Name, }, } // Default values log.Debug(" Applying default data to context") context["private_ipv4"] = "$private_ipv4" // Provided by CoreOS context["public_ipv4"] = "$public_ipv4" // Provided by CoreOS // Merge environment/provider values var data map[string]interface{} log.Debug(" Applying environment data to context") if err := mergo.Merge(&data, *envData); err != nil { return nil, err } log.Debug(" Applying provider data to context") if err := mergo.Merge(&data, provider.Data); err != nil { return nil, err } // Add/Override values from extra data if dataFile != nil { log.Debug(" Applying extra data to context") var extraData map[string]interface{} if err := util.LoadYAMLFromFile(*dataFile, &extraData); err != nil { log.Error("Error loading/parsing extra data from file:\n %s", *dataFile) return nil, err } if err := mergo.Merge(&data, extraData); err != nil { return nil, err } } // Set result into context for k, v := range data { context[k] = v } return &context, nil }
// Generate a scrypt hash given a request. func GenerateScryptHash(hr *HashRequest) (*HashResponse, error) { // First, grab the hash options and either use what the user specified or // set them to the defaults (recommended). if err := mergo.Merge(hr.Options, DefaultHashRequestOptions); err != nil { return nil, errors.New("Invalid options specified.") } // Build our scrypt config. config := uscrypt.Config{ LogN: int8(hr.Options.N), R: hr.Options.R, P: hr.Options.P, SaltSize: hr.Options.SaltSize, HashSize: hr.Options.HashSize, } // Compute the scrypt hash. hash, err := uscrypt.HashPassword([]byte(hr.String), &config) if err != nil { return nil, errors.New("Could not compute the scrypt hash.") } // Send our response to the user. return &HashResponse{Hash: hash}, nil }
func MergeManifest(source Manifest, s *State) (Manifest, error) { merged := source merged.Deployments = map[string]Deployment{} // Copy every non-global DC to the map (we don't want to destroy the // original source values, and we want to explicitly not end up with a // datacentre named "Global"). for k, v := range source.Deployments { if k == "Global" { continue } merged.Deployments[k] = v } // If we have a global deployment, fill in empty values in existing // deployments using this, and add missing deployments. if global, ok := source.Deployments["Global"]; ok { for k := range s.Datacentres { // If we already have a defined deploy with this name, fill // in the blanks from Global... if defined, ok := merged.Deployments[k]; ok { mergo.Merge(&defined, global) // fill in empty values merged.Deployments[k] = defined // copy it back to the map } else { merged.Deployments[k] = global } // Now add datacentre-wide environment variables for ke, ve := range s.Datacentres[k].Env { merged.Deployments[k].Environment[ke] = ve } } } return merged, nil }
// MergeSingle merges the default with the given config and returns the result func (c Template) MergeSingle(cfg Template) (config Template) { config = cfg mergo.Merge(&config, c) return }
// MergeSingle merges the default with the given config and returns the result func (c *Websocket) MergeSingle(cfg *Websocket) (config *Websocket) { config = cfg mergo.Merge(config, c) return }
// MergeSingle merges the default with the given config and returns the result func (c Iris) MergeSingle(cfg Iris) (config Iris) { config = cfg mergo.Merge(&config, c) return }
func (users *Users) tokenCreateWithOptions(user User, options TokenOptions) (Token, error) { mergo.Merge(&options, DefaultTokenOptions) userJson, err := json.Marshal(user) if err != nil { return "", fmt.Errorf("unable to json-encode user %v: %v", user, err) } token, err := tokenGenerate(user.ID, options.SecretSize) if err != nil { return "", err } key := fmt.Sprintf(tokenKeyFormat, token) err = users.redis.Set(key, string(userJson), options.Duration).Err() if err != nil { return "", fmt.Errorf("redis.Set(%v, %s, %v) failed: %v", key, userJson, options.Duration, err) } tokenListKey := fmt.Sprintf(tokenListKeyFormat, user.ID) err = users.redis.SAdd(tokenListKey, key).Err() if err != nil { return "", fmt.Errorf("redis.Sadd(%v, %s) failed: %v", tokenListKey, key) } return token, nil }
// MergeSingle merges the default with the given config and returns the result func (c Server) MergeSingle(cfg Server) (config Server) { config = cfg mergo.Merge(&config, c) return }
func Merge(dst runtime.Object, fragment, kind string) error { // Ok, this is a little hairy, we'd rather not force the user to specify a kind for their JSON // So we pull it into a map, add the Kind field, and then reserialize. // We also pull the apiVersion for proper parsing var intermediate interface{} if err := json.Unmarshal([]byte(fragment), &intermediate); err != nil { return err } dataMap, ok := intermediate.(map[string]interface{}) if !ok { return fmt.Errorf("Expected a map, found something else: %s", fragment) } version, found := dataMap["apiVersion"] if !found { return fmt.Errorf("Inline JSON requires an apiVersion field") } versionString, ok := version.(string) if !ok { return fmt.Errorf("apiVersion must be a string") } codec := runtime.CodecFor(api.Scheme, versionString) dataMap["kind"] = kind data, err := json.Marshal(intermediate) if err != nil { return err } src, err := codec.Decode(data) if err != nil { return err } return mergo.Merge(dst, src) }
// Generate a bcrypt hash given a request. func GenerateBcryptHash(hr *HashRequest) (*HashResponse, error) { // First, grab the hash options and either use what the user specified or // set them to the defaults (recommended). if err := mergo.Merge(hr.Options, DefaultHashRequestOptions); err != nil { return nil, errors.New("Invalid options specified.") } // If the user specified no cost (or a cost smaller than the minimum // allowed), we'll automatically set the cost to the bcrypt library's // recommended value. if hr.Options.Cost < bcrypt.MinCost { hr.Options.Cost = bcrypt.DefaultCost } // Compute the bcrypt hash. hash, err := bcrypt.GenerateFromPassword([]byte(hr.String), hr.Options.Cost) if err != nil { return nil, errors.New("Could not compute the bcrypt hash.") } // Send our response to the user. return &HashResponse{Hash: string(hash)}, nil }
// MergeSingle merges the default with the given config and returns the result func (c Redis) MergeSingle(cfg Redis) (config Redis) { config = cfg mergo.Merge(&config, c) return }
// MergeSingle merges the default with the given config and returns the result func (c Sessions) MergeSingle(cfg Sessions) (config Sessions) { config = cfg mergo.Merge(&config, c) return }
// MergeSingle merges the default with the given config and returns the result func (c Logger) MergeSingle(cfg Logger) (config Logger) { config = cfg mergo.Merge(&config, c) return }
// MergeSingle merges the default with the given config and returns the result func (c BasicAuth) MergeSingle(cfg BasicAuth) (config BasicAuth) { config = cfg mergo.Merge(&config, c) return }
// ClientConfig implements ClientConfig func (config *DirectClientConfig) ClientConfig() (*client.Config, error) { if err := config.ConfirmUsable(); err != nil { return nil, err } configAuthInfo := config.getAuthInfo() configClusterInfo := config.getCluster() clientConfig := &client.Config{} clientConfig.Host = configClusterInfo.Server if u, err := url.ParseRequestURI(clientConfig.Host); err == nil && u.Opaque == "" && len(u.Path) > 1 { u.RawQuery = "" u.Fragment = "" clientConfig.Host = u.String() } if len(configClusterInfo.APIVersion) != 0 { gv, err := unversioned.ParseGroupVersion(configClusterInfo.APIVersion) if err != nil { return nil, err } clientConfig.GroupVersion = &gv } // only try to read the auth information if we are secure if client.IsConfigTransportTLS(*clientConfig) { var err error // mergo is a first write wins for map value and a last writing wins for interface values // NOTE: This behavior changed with https://github.com/imdario/mergo/commit/d304790b2ed594794496464fadd89d2bb266600a. // Our mergo.Merge version is older than this change. userAuthPartialConfig, err := getUserIdentificationPartialConfig(configAuthInfo, config.fallbackReader) if err != nil { return nil, err } mergo.Merge(clientConfig, userAuthPartialConfig) serverAuthPartialConfig, err := getServerIdentificationPartialConfig(configAuthInfo, configClusterInfo) if err != nil { return nil, err } mergo.Merge(clientConfig, serverAuthPartialConfig) } return clientConfig, nil }