func validateConfig(cfg, old *config.Config) (*environConfig, error) { // Check for valid changes for the base config values. if err := config.Validate(cfg, old); err != nil { return nil, err } validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) if err != nil { return nil, err } ecfg := &environConfig{cfg, validated} if vpcID := ecfg.vpcID(); isVPCIDSetButInvalid(vpcID) { return nil, fmt.Errorf("vpc-id: %q is not a valid AWS VPC ID", vpcID) } else if !isVPCIDSet(vpcID) && ecfg.forceVPCID() { return nil, fmt.Errorf("cannot use vpc-id-force without specifying vpc-id as well") } if old != nil { attrs := old.UnknownAttrs() if vpcID, _ := attrs["vpc-id"].(string); vpcID != ecfg.vpcID() { return nil, fmt.Errorf("cannot change vpc-id from %q to %q", vpcID, ecfg.vpcID()) } if forceVPCID, _ := attrs["vpc-id-force"].(bool); forceVPCID != ecfg.forceVPCID() { return nil, fmt.Errorf("cannot change vpc-id-force from %v to %v", forceVPCID, ecfg.forceVPCID()) } } // ssl-hostname-verification cannot be disabled if !ecfg.SSLHostnameVerification() { return nil, fmt.Errorf("disabling ssh-hostname-verification is not supported") } return ecfg, nil }
// PrepareForBootstrap is specified in the EnvironProvider interface. func (prov *azureEnvironProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { // Ensure that internal configuration is not specified, and then set // what we can now. We only need to do this during bootstrap. Validate // will check for changes later. unknownAttrs := cfg.UnknownAttrs() for _, key := range internalConfigAttributes { if _, ok := unknownAttrs[key]; ok { return nil, errors.Errorf(`internal config %q must not be specified`, key) } } // Record the UUID that will be used for the controller environment. cfg, err := cfg.Apply(map[string]interface{}{ configAttrControllerResourceGroup: resourceGroupName(cfg), }) if err != nil { return nil, errors.Annotate(err, "recording controller-resource-group") } env, err := prov.Open(cfg) if err != nil { return nil, errors.Trace(err) } if ctx.ShouldVerifyCredentials() { if err := verifyCredentials(env.(*azureEnviron)); err != nil { return nil, errors.Trace(err) } } return env, nil }
// update applies changes from the provided config to the env config. // Changes to any immutable attributes result in an error. func (c *environConfig) update(cfg *config.Config) error { // Validate the updates. newValidConfig does not modify the "known" // config attributes so it is safe to call Validate here first. if err := config.Validate(cfg, c.Config); err != nil { return errors.Trace(err) } updates, err := newValidConfig(cfg, configDefaults) if err != nil { return errors.Trace(err) } // Check that no immutable fields have changed. attrs := updates.UnknownAttrs() for _, field := range configImmutableFields { if attrs[field] != c.attrs[field] { return errors.Errorf("%s: cannot change from %v to %v", field, c.attrs[field], attrs[field]) } } // Apply the updates. c.Config = cfg c.attrs = cfg.UnknownAttrs() return nil }
func (p manualProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { if _, ok := cfg.UnknownAttrs()["storage-auth-key"]; !ok { uuid, err := utils.NewUUID() if err != nil { return nil, err } cfg, err = cfg.Apply(map[string]interface{}{ "storage-auth-key": uuid.String(), }) if err != nil { return nil, err } } if use, ok := cfg.UnknownAttrs()["use-sshstorage"].(bool); ok && !use { return nil, fmt.Errorf("use-sshstorage must not be specified") } envConfig, err := p.validate(cfg, nil) if err != nil { return nil, err } cfg, err = cfg.Apply(envConfig.attrs) if err != nil { return nil, err } envConfig = newEnvironConfig(cfg, envConfig.attrs) if err := ensureBootstrapUbuntuUser(ctx, envConfig); err != nil { return nil, err } return p.open(envConfig) }
// SetConfig is specified in the Environ interface. func (env *azureEnviron) SetConfig(cfg *config.Config) error { env.mu.Lock() defer env.mu.Unlock() var old *config.Config if env.config != nil { old = env.config.Config } ecfg, err := validateConfig(cfg, old) if err != nil { return err } env.config = ecfg // Initialise clients. env.compute = compute.NewWithBaseURI(ecfg.endpoint, env.config.subscriptionId) env.resources = resources.NewWithBaseURI(ecfg.endpoint, env.config.subscriptionId) env.storage = storage.NewWithBaseURI(ecfg.endpoint, env.config.subscriptionId) env.network = network.NewWithBaseURI(ecfg.endpoint, env.config.subscriptionId) clients := map[string]*autorest.Client{ "azure.compute": &env.compute.Client, "azure.resources": &env.resources.Client, "azure.storage": &env.storage.Client, "azure.network": &env.network.Client, } if env.provider.config.Sender != nil { env.config.token.SetSender(env.provider.config.Sender) } for id, client := range clients { client.Authorizer = env.config.token logger := loggo.GetLogger(id) if env.provider.config.Sender != nil { client.Sender = env.provider.config.Sender } client.ResponseInspector = tracingRespondDecorator(logger) client.RequestInspector = tracingPrepareDecorator(logger) if env.provider.config.RequestInspector != nil { tracer := client.RequestInspector inspector := env.provider.config.RequestInspector client.RequestInspector = func(p autorest.Preparer) autorest.Preparer { p = tracer(p) p = inspector(p) return p } } } // Invalidate instance types when the location changes. if old != nil { oldLocation := old.UnknownAttrs()["location"].(string) if env.config.location != oldLocation { env.instanceTypes = nil } } return nil }
// PrepareForCreateEnvironment is specified in the EnvironProvider interface. func (p maasEnvironProvider) PrepareForCreateEnvironment(cfg *config.Config) (*config.Config, error) { attrs := cfg.UnknownAttrs() oldName, found := attrs["maas-agent-name"] if found && oldName != "" { return nil, errAgentNameAlreadySet } attrs["maas-agent-name"] = cfg.UUID() return cfg.Apply(attrs) }
func (e *manualEnviron) SetConfig(cfg *config.Config) error { e.mu.Lock() defer e.mu.Unlock() _, err := manualProvider{}.validate(cfg, e.cfg.Config) if err != nil { return err } e.cfg = newModelConfig(cfg, cfg.UnknownAttrs()) return nil }
// SecretAttrs is specified in the EnvironProvider interface. func (prov *azureEnvironProvider) SecretAttrs(cfg *config.Config) (map[string]string, error) { unknownAttrs := cfg.UnknownAttrs() secretAttrs := map[string]string{ configAttrAppPassword: unknownAttrs[configAttrAppPassword].(string), } if storageAccountKey, ok := unknownAttrs[configAttrStorageAccountKey].(string); ok { secretAttrs[configAttrStorageAccountKey] = storageAccountKey } return secretAttrs, nil }
// PrepareForBootstrap is specified in the EnvironProvider interface. func (p manualProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { if _, err := p.validate(cfg, nil); err != nil { return nil, err } envConfig := newModelConfig(cfg, cfg.UnknownAttrs()) if err := ensureBootstrapUbuntuUser(ctx, envConfig); err != nil { return nil, err } return p.open(envConfig) }
func (prov maasEnvironProvider) Validate(cfg, oldCfg *config.Config) (*config.Config, error) { // Validate base configuration change before validating MAAS specifics. err := config.Validate(cfg, oldCfg) if err != nil { return nil, err } validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) if err != nil { return nil, err } // Add MAAS specific defaults. providerDefaults := make(map[string]interface{}) // Storage. if _, ok := cfg.StorageDefaultBlockSource(); !ok { providerDefaults[config.StorageDefaultBlockSourceKey] = maasStorageProviderType } if len(providerDefaults) > 0 { if cfg, err = cfg.Apply(providerDefaults); err != nil { return nil, err } } if oldCfg != nil { oldAttrs := oldCfg.UnknownAttrs() validMaasAgentName := false if oldName, ok := oldAttrs["maas-agent-name"]; !ok || oldName == nil { // If maas-agent-name was nil (because the config was // generated pre-1.16.2 the only correct value for it is "" // See bug #1256179 validMaasAgentName = (validated["maas-agent-name"] == "") } else { validMaasAgentName = (validated["maas-agent-name"] == oldName) } if !validMaasAgentName { return nil, fmt.Errorf("cannot change maas-agent-name") } } envCfg := new(maasEnvironConfig) envCfg.Config = cfg envCfg.attrs = validated server := envCfg.maasServer() serverURL, err := url.Parse(server) if err != nil || serverURL.Scheme == "" || serverURL.Host == "" { return nil, fmt.Errorf("malformed maas-server URL '%v': %s", server, err) } oauth := envCfg.maasOAuth() if strings.Count(oauth, ":") != 2 { return nil, errMalformedMaasOAuth } return cfg.Apply(envCfg.attrs) }
func (p manualProvider) Open(cfg *config.Config) (environs.Environ, error) { _, err := p.validate(cfg, nil) if err != nil { return nil, err } // validate adds missing manual-specific config attributes // with their defaults in the result; we don't wnat that in // Open. envConfig := newEnvironConfig(cfg, cfg.UnknownAttrs()) return p.open(envConfig) }
// PrepareForCreateEnvironment is specified in the EnvironProvider interface. func (p environProvider) PrepareForCreateEnvironment(cfg *config.Config) (*config.Config, error) { attrs := cfg.UnknownAttrs() if _, ok := attrs["control-bucket"]; !ok { uuid, err := utils.NewUUID() if err != nil { return nil, errors.Trace(err) } attrs["control-bucket"] = fmt.Sprintf("%x", uuid.Raw()) } return cfg.Apply(attrs) }
func (ts configTestSpec) checkAttrs(c *gc.C, attrs map[string]interface{}, cfg *config.Config) { for field, expected := range cfg.UnknownAttrs() { value := attrs[field] if field == "auth-file" && value != nil { filename := value.(string) if filename != "" { value = interface{}(filepath.Join(ts.rootDir, filename)) } } c.Check(value, gc.Equals, expected) } }
func validateConfig(cfg, old *config.Config) (*environConfig, error) { // Check for valid changes for the base config values. if err := config.Validate(cfg, old); err != nil { return nil, err } validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) if err != nil { return nil, err } // Add EC2 specific defaults. providerDefaults := make(map[string]interface{}) // Storage. if _, ok := cfg.StorageDefaultBlockSource(); !ok { providerDefaults[config.StorageDefaultBlockSourceKey] = EBS_ProviderType } if len(providerDefaults) > 0 { if cfg, err = cfg.Apply(providerDefaults); err != nil { return nil, err } } ecfg := &environConfig{cfg, validated} if ecfg.accessKey() == "" || ecfg.secretKey() == "" { auth, err := aws.EnvAuth() if err != nil || ecfg.accessKey() != "" || ecfg.secretKey() != "" { return nil, fmt.Errorf("environment has no access-key or secret-key") } ecfg.attrs["access-key"] = auth.AccessKey ecfg.attrs["secret-key"] = auth.SecretKey } if _, ok := aws.Regions[ecfg.region()]; !ok { return nil, fmt.Errorf("invalid region name %q", ecfg.region()) } if old != nil { attrs := old.UnknownAttrs() if region, _ := attrs["region"].(string); ecfg.region() != region { return nil, fmt.Errorf("cannot change region from %q to %q", region, ecfg.region()) } if bucket, _ := attrs["control-bucket"].(string); ecfg.controlBucket() != bucket { return nil, fmt.Errorf("cannot change control-bucket from %q to %q", bucket, ecfg.controlBucket()) } } // ssl-hostname-verification cannot be disabled if !ecfg.SSLHostnameVerification() { return nil, fmt.Errorf("disabling ssh-hostname-verification is not supported") } return ecfg, nil }
// PrepareForCreateEnvironment is specified in the EnvironProvider interface. func (joyentProvider) PrepareForCreateEnvironment(cfg *config.Config) (*config.Config, error) { // Turn an incomplete config into a valid one, if possible. attrs := cfg.UnknownAttrs() if _, ok := attrs["control-dir"]; !ok { uuid, err := utils.NewUUID() if err != nil { return nil, errors.Trace(err) } attrs["control-dir"] = fmt.Sprintf("%x", uuid.Raw()) } return cfg.Apply(attrs) }
func prepareConfig(cfg *config.Config) (*config.Config, error) { // Turn an incomplete config into a valid one, if possible. attrs := cfg.UnknownAttrs() if _, ok := attrs["control-dir"]; !ok { uuid, err := utils.NewUUID() if err != nil { return nil, err } attrs["control-dir"] = fmt.Sprintf("%x", uuid.Raw()) } return cfg.Apply(attrs) }
// parseCredentials extracts the OAuth2 info from the config from the // individual fields (falling back on the JSON file). func parseCredentials(cfg *config.Config) (*google.Credentials, error) { attrs := cfg.UnknownAttrs() values := make(map[string]string) for _, field := range configAuthFields { if existing, ok := attrs[field].(string); ok && existing != "" { for key, candidate := range osEnvFields { if field == candidate { values[key] = existing break } } } } return google.NewCredentials(values) }
func (p maasEnvironProvider) Prepare(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { attrs := cfg.UnknownAttrs() oldName, found := attrs["maas-agent-name"] if found && oldName != "" { return nil, errAgentNameAlreadySet } uuid, err := utils.NewUUID() if err != nil { return nil, err } attrs["maas-agent-name"] = uuid.String() cfg, err = cfg.Apply(attrs) if err != nil { return nil, err } return p.Open(cfg) }
func (p manualProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { if use, ok := cfg.UnknownAttrs()["use-sshstorage"].(bool); ok && !use { return nil, fmt.Errorf("use-sshstorage must not be specified") } envConfig, err := p.validate(cfg, nil) if err != nil { return nil, err } cfg, err = cfg.Apply(envConfig.attrs) if err != nil { return nil, err } envConfig = newEnvironConfig(cfg, envConfig.attrs) if err := ensureBootstrapUbuntuUser(ctx, envConfig); err != nil { return nil, err } return p.open(envConfig) }
// Open implements environs.EnvironProvider.Open. func (environProvider) Open(cfg *config.Config) (environs.Environ, error) { logger.Infof("opening environment %q", cfg.Name()) if _, ok := cfg.AgentVersion(); !ok { newCfg, err := cfg.Apply(map[string]interface{}{ "agent-version": version.Current.Number.String(), }) if err != nil { return nil, err } cfg = newCfg } // Set the "namespace" attribute. We do this here, and not in Prepare, // for backwards compatibility: older versions did not store the namespace // in config. if namespace, _ := cfg.UnknownAttrs()["namespace"].(string); namespace == "" { username := os.Getenv("USER") if username == "" { u, err := userCurrent() if err != nil { return nil, fmt.Errorf("failed to determine username for namespace: %v", err) } username = u.Username } var err error namespace = fmt.Sprintf("%s-%s", username, cfg.Name()) cfg, err = cfg.Apply(map[string]interface{}{"namespace": namespace}) if err != nil { return nil, fmt.Errorf("failed to create namespace: %v", err) } } // Do the initial validation on the config. localConfig, err := providerInstance.newConfig(cfg) if err != nil { return nil, err } if err := VerifyPrerequisites(localConfig.container()); err != nil { return nil, fmt.Errorf("failed verification of local provider prerequisites: %v", err) } environ := &localEnviron{name: cfg.Name()} if err := environ.SetConfig(cfg); err != nil { return nil, fmt.Errorf("failure setting config: %v", err) } return environ, nil }
func adjustDefaults(cfg *config.Config, defaults map[string]interface{}) (map[string]interface{}, []string) { var unset []string updated := make(map[string]interface{}) for k, v := range defaults { updated[k] = v } // Set the proper default namespace. raw := updated[cfgNamespace] if raw == nil || raw.(string) == "" { raw = cfg.Name() updated[cfgNamespace] = raw } if val, ok := cfg.UnknownAttrs()[cfgNamespace]; ok && val == "" { unset = append(unset, cfgNamespace) } return updated, unset }
// parseCredentials extracts the OAuth2 info from the config from the // individual fields (falling back on the JSON file). func parseCredentials(cfg *config.Config) (*google.Credentials, error) { attrs := cfg.UnknownAttrs() // Try the auth fields first. values := make(map[string]string) for _, field := range configAuthFields { if existing, ok := attrs[field].(string); ok && existing != "" { for key, candidate := range osEnvFields { if field == candidate { values[key] = existing break } } } } if len(values) > 0 { creds, err := google.NewCredentials(values) if err != nil { return nil, errors.Trace(err) } return creds, nil } // Fall back to the auth file. filename, ok := attrs[cfgAuthFile].(string) if !ok || filename == "" { // The missing credentials will be caught later. return nil, nil } authFile, err := os.Open(filename) if err != nil { return nil, errors.Trace(err) } defer authFile.Close() creds, err := google.ParseJSONKey(authFile) if err != nil { return nil, errors.Trace(err) } return creds, nil }
func (e *manualEnviron) SetConfig(cfg *config.Config) error { e.cfgmutex.Lock() defer e.cfgmutex.Unlock() _, err := manualProvider{}.validate(cfg, e.cfg.Config) if err != nil { return err } envConfig := newEnvironConfig(cfg, cfg.UnknownAttrs()) // Set storage. If "use-sshstorage" is true then use the SSH storage. // Otherwise, use HTTP storage. // // We don't change storage once it's been set. Storage parameters // are fixed at bootstrap time, and it is not possible to change // them. if e.storage == nil { var stor storage.Storage if envConfig.useSSHStorage() { storageDir := e.StorageDir() storageTmpdir := path.Join(agent.DefaultPaths.DataDir, storageTmpSubdir) stor, err = newSSHStorage("ubuntu@"+e.cfg.bootstrapHost(), storageDir, storageTmpdir) if err != nil { return fmt.Errorf("initialising SSH storage failed: %v", err) } } else { caCertPEM, ok := envConfig.CACert() if !ok { // should not be possible to validate base config return fmt.Errorf("ca-cert not set") } authkey := envConfig.storageAuthKey() stor, err = httpstorage.ClientTLS(envConfig.storageAddr(), caCertPEM, authkey) if err != nil { return fmt.Errorf("initialising HTTPS storage failed: %v", err) } } e.storage = stor } e.cfg = envConfig return nil }
func (p environProvider) Validate(cfg, old *config.Config) (valid *config.Config, err error) { // Check for valid changes for the base config values. if err := config.Validate(cfg, old); err != nil { return nil, err } validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) if err != nil { return nil, err } ecfg := &environConfig{cfg, validated} if ecfg.accessKey() == "" || ecfg.secretKey() == "" { auth, err := aws.EnvAuth() if err != nil || ecfg.accessKey() != "" || ecfg.secretKey() != "" { return nil, fmt.Errorf("environment has no access-key or secret-key") } ecfg.attrs["access-key"] = auth.AccessKey ecfg.attrs["secret-key"] = auth.SecretKey } if _, ok := aws.Regions[ecfg.region()]; !ok { return nil, fmt.Errorf("invalid region name %q", ecfg.region()) } if old != nil { attrs := old.UnknownAttrs() if region, _ := attrs["region"].(string); ecfg.region() != region { return nil, fmt.Errorf("cannot change region from %q to %q", region, ecfg.region()) } if bucket, _ := attrs["control-bucket"].(string); ecfg.controlBucket() != bucket { return nil, fmt.Errorf("cannot change control-bucket from %q to %q", bucket, ecfg.controlBucket()) } } // ssl-hostname-verification cannot be disabled if !ecfg.SSLHostnameVerification() { return nil, fmt.Errorf("disabling ssh-hostname-verification is not supported") } // Apply the coerced unknown values back into the config. return cfg.Apply(ecfg.attrs) }
// PrepareForBootstrap implements environs.EnvironProvider.PrepareForBootstrap. func (p environProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { cfg, err := p.PrepareForCreateEnvironment(cfg) if err != nil { return nil, errors.Trace(err) } // The user must not set bootstrap-ip; this is determined by the provider, // and its presence used to determine whether the environment has yet been // bootstrapped. if _, ok := cfg.UnknownAttrs()["bootstrap-ip"]; ok { return nil, errors.Errorf("bootstrap-ip must not be specified") } err = checkLocalPort(cfg.StatePort(), "state port") if err != nil { return nil, errors.Trace(err) } err = checkLocalPort(cfg.APIPort(), "API port") if err != nil { return nil, errors.Trace(err) } return p.Open(cfg) }
func validateConfig(cfg, old *config.Config) (*environConfig, error) { // Check for valid changes for the base config values. if err := config.Validate(cfg, old); err != nil { return nil, err } validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) if err != nil { return nil, err } ecfg := &environConfig{cfg, validated} if ecfg.accessKey() == "" || ecfg.secretKey() == "" { auth, err := aws.EnvAuth() if err != nil || ecfg.accessKey() != "" || ecfg.secretKey() != "" { return nil, fmt.Errorf("model has no access-key or secret-key") } ecfg.attrs["access-key"] = auth.AccessKey ecfg.attrs["secret-key"] = auth.SecretKey } if _, ok := aws.Regions[ecfg.region()]; !ok { return nil, fmt.Errorf("invalid region name %q", ecfg.region()) } if old != nil { attrs := old.UnknownAttrs() if region, _ := attrs["region"].(string); ecfg.region() != region { return nil, fmt.Errorf("cannot change region from %q to %q", region, ecfg.region()) } } // ssl-hostname-verification cannot be disabled if !ecfg.SSLHostnameVerification() { return nil, fmt.Errorf("disabling ssh-hostname-verification is not supported") } return ecfg, nil }
// update applies changes from the provided config to the env config. // Changes to any immutable attributes result in an error. func (c *environConfig) update(cfg *config.Config) error { // Validate the updates. newValidConfig does not modify the "known" // config attributes so it is safe to call Validate here first. if err := config.Validate(cfg, c.Config); err != nil { return errors.Trace(err) } updates, err := newValidConfig(cfg, configDefaults) if err != nil { return errors.Trace(err) } // Check that no immutable fields have changed. attrs := updates.UnknownAttrs() if err := ensureImmutableFields(c.attrs, attrs); err != nil { return errors.Trace(err) } // Apply the updates. // TODO(ericsnow) Should updates.Config be set in instead of cfg? c.Config = cfg c.attrs = cfg.UnknownAttrs() return nil }
// PrepareForCreateEnvironment is specified in the EnvironProvider interface. func (p environProvider) PrepareForCreateEnvironment(cfg *config.Config) (*config.Config, error) { attrs := map[string]interface{}{ // We must not proxy SSH through the API server in a // local provider environment. Besides not being useful, // it may not work; there is no requirement for sshd to // be available on machine-0. "proxy-ssh": false, } if _, ok := cfg.AgentVersion(); !ok { attrs["agent-version"] = version.Current.Number.String() } if namespace, _ := cfg.UnknownAttrs()["namespace"].(string); namespace == "" { username := os.Getenv("USER") if username == "" { u, err := userCurrent() if err != nil { return nil, errors.Annotate(err, "failed to determine username for namespace") } username = u.Username } attrs["namespace"] = fmt.Sprintf("%s-%s", username, cfg.Name()) } setIfNotBlank := func(key, value string) { if value != "" { attrs[key] = value } } // If the user has specified no values for any of the four normal // proxies, then look in the environment and set them. logger.Tracef("Look for proxies?") if cfg.HttpProxy() == "" && cfg.HttpsProxy() == "" && cfg.FtpProxy() == "" && cfg.NoProxy() == "" { proxySettings := proxy.DetectProxies() logger.Tracef("Proxies detected %#v", proxySettings) setIfNotBlank(config.HttpProxyKey, proxySettings.Http) setIfNotBlank(config.HttpsProxyKey, proxySettings.Https) setIfNotBlank(config.FtpProxyKey, proxySettings.Ftp) setIfNotBlank(config.NoProxyKey, proxySettings.NoProxy) } if version.Current.OS == version.Ubuntu { if cfg.AptHttpProxy() == "" && cfg.AptHttpsProxy() == "" && cfg.AptFtpProxy() == "" { proxySettings, err := detectPackageProxies() if err != nil { return nil, errors.Trace(err) } setIfNotBlank(config.AptHttpProxyKey, proxySettings.Http) setIfNotBlank(config.AptHttpsProxyKey, proxySettings.Https) setIfNotBlank(config.AptFtpProxyKey, proxySettings.Ftp) } } cfg, err := cfg.Apply(attrs) if err != nil { return nil, errors.Trace(err) } // Make sure everything is valid. cfg, err = p.Validate(cfg, nil) if err != nil { return nil, errors.Trace(err) } return cfg, nil }
// PrepareForBootstrap implements environs.EnvironProvider.PrepareForBootstrap. func (p environProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { attrs := map[string]interface{}{ // We must not proxy SSH through the API server in a // local provider environment. Besides not being useful, // it may not work; there is no requirement for sshd to // be available on machine-0. "proxy-ssh": false, } if _, ok := cfg.AgentVersion(); !ok { attrs["agent-version"] = version.Current.String() } if namespace, _ := cfg.UnknownAttrs()["namespace"].(string); namespace == "" { username := os.Getenv("USER") if username == "" { u, err := userCurrent() if err != nil { return nil, errors.Annotate(err, "failed to determine username for namespace") } username = u.Username } attrs["namespace"] = fmt.Sprintf("%s-%s", username, cfg.Name()) } setIfNotBlank := func(key, value string) { if value != "" { attrs[key] = value } } // If the user has specified no values for any of the four normal // proxies, then look in the environment and set them. logger.Tracef("Look for proxies?") if cfg.HttpProxy() == "" && cfg.HttpsProxy() == "" && cfg.FtpProxy() == "" && cfg.NoProxy() == "" { proxySettings := proxy.DetectProxies() logger.Tracef("Proxies detected %#v", proxySettings) setIfNotBlank(config.HttpProxyKey, proxySettings.Http) setIfNotBlank(config.HttpsProxyKey, proxySettings.Https) setIfNotBlank(config.FtpProxyKey, proxySettings.Ftp) setIfNotBlank(config.NoProxyKey, proxySettings.NoProxy) } if jujuos.HostOS() == jujuos.Ubuntu { if cfg.AptHttpProxy() == "" && cfg.AptHttpsProxy() == "" && cfg.AptFtpProxy() == "" { proxySettings, err := detectPackageProxies() if err != nil { return nil, errors.Trace(err) } setIfNotBlank(config.AptHttpProxyKey, proxySettings.Http) setIfNotBlank(config.AptHttpsProxyKey, proxySettings.Https) setIfNotBlank(config.AptFtpProxyKey, proxySettings.Ftp) } } cfg, err := cfg.Apply(attrs) if err != nil { return nil, errors.Trace(err) } // Make sure everything is valid. cfg, err = p.Validate(cfg, nil) if err != nil { return nil, errors.Trace(err) } // The user must not set bootstrap-ip; this is determined by the provider, // and its presence used to determine whether the environment has yet been // bootstrapped. if _, ok := cfg.UnknownAttrs()["bootstrap-ip"]; ok { return nil, errors.Errorf("bootstrap-ip must not be specified") } err = checkLocalPort(cfg.StatePort(), "state port") if err != nil { return nil, errors.Trace(err) } err = checkLocalPort(cfg.APIPort(), "API port") if err != nil { return nil, errors.Trace(err) } return p.Open(cfg) }
func (ts configTestSpec) checkAttrs(c *gc.C, attrs map[string]interface{}, cfg *config.Config) { for field, expected := range cfg.UnknownAttrs() { value := attrs[field] c.Check(value, gc.Equals, expected) } }