github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/openstack/config.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package openstack
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/schema"
    10  	"github.com/juju/utils"
    11  	"gopkg.in/juju/environschema.v1"
    12  
    13  	"github.com/juju/juju/environs/config"
    14  )
    15  
    16  const (
    17  	ExternalNetworkKey    = "external-network"
    18  	NetworkKey            = "network"
    19  	PolicyTargetGroupKey  = "policy-target-group"
    20  	UseDefaultSecgroupKey = "use-default-secgroup"
    21  	UseOpenstackGBPKey    = "use-openstack-gbp"
    22  	UseFloatingIPKey      = "use-floating-ip"
    23  )
    24  
    25  var configSchema = environschema.Fields{
    26  	UseFloatingIPKey: {
    27  		Description: "Whether a floating IP address is required to give the nodes a public IP address. Some installations assign public IP addresses by default without requiring a floating IP address.",
    28  		Type:        environschema.Tbool,
    29  	},
    30  	UseDefaultSecgroupKey: {
    31  		Description: `Whether new machine instances should have the "default" Openstack security group assigned in addition to juju defined security groups.`,
    32  		Type:        environschema.Tbool,
    33  	},
    34  	NetworkKey: {
    35  		Description: "The network label or UUID to bring machines up on when multiple networks exist.",
    36  		Type:        environschema.Tstring,
    37  	},
    38  	ExternalNetworkKey: {
    39  		Description: "The network label or UUID to create floating IP addresses on when multiple external networks exist.",
    40  		Type:        environschema.Tstring,
    41  	},
    42  	UseOpenstackGBPKey: {
    43  		Description: "Whether to use Neutrons Group-Based Policy",
    44  		Type:        environschema.Tbool,
    45  	},
    46  	PolicyTargetGroupKey: {
    47  		Description: "The UUID of Policy Target Group to use for Policy Targets created.",
    48  		Type:        environschema.Tstring,
    49  	},
    50  }
    51  
    52  var configDefaults = schema.Defaults{
    53  	UseFloatingIPKey:      false,
    54  	UseDefaultSecgroupKey: false,
    55  	NetworkKey:            "",
    56  	ExternalNetworkKey:    "",
    57  	UseOpenstackGBPKey:    false,
    58  	PolicyTargetGroupKey:  "",
    59  }
    60  
    61  var configFields = func() schema.Fields {
    62  	fs, _, err := configSchema.ValidationSchema()
    63  	if err != nil {
    64  		panic(err)
    65  	}
    66  	return fs
    67  }()
    68  
    69  type environConfig struct {
    70  	*config.Config
    71  	attrs map[string]interface{}
    72  }
    73  
    74  func (c *environConfig) useFloatingIP() bool {
    75  	return c.attrs[UseFloatingIPKey].(bool)
    76  }
    77  
    78  func (c *environConfig) useDefaultSecurityGroup() bool {
    79  	return c.attrs[UseDefaultSecgroupKey].(bool)
    80  }
    81  
    82  func (c *environConfig) network() string {
    83  	return c.attrs[NetworkKey].(string)
    84  }
    85  
    86  func (c *environConfig) externalNetwork() string {
    87  	return c.attrs[ExternalNetworkKey].(string)
    88  }
    89  
    90  func (c *environConfig) useOpenstackGBP() bool {
    91  	return c.attrs[UseOpenstackGBPKey].(bool)
    92  }
    93  
    94  func (c *environConfig) policyTargetGroup() string {
    95  	return c.attrs[PolicyTargetGroupKey].(string)
    96  }
    97  
    98  type AuthMode string
    99  
   100  const (
   101  	AuthKeyPair  AuthMode = "keypair"
   102  	AuthLegacy   AuthMode = "legacy"
   103  	AuthUserPass AuthMode = "userpass"
   104  )
   105  
   106  // Schema returns the configuration schema for an environment.
   107  func (EnvironProvider) Schema() environschema.Fields {
   108  	fields, err := config.Schema(configSchema)
   109  	if err != nil {
   110  		panic(err)
   111  	}
   112  	return fields
   113  }
   114  
   115  // ConfigSchema returns extra config attributes specific
   116  // to this provider only.
   117  func (p EnvironProvider) ConfigSchema() schema.Fields {
   118  	return configFields
   119  }
   120  
   121  // ConfigDefaults returns the default values for the
   122  // provider specific config attributes.
   123  func (p EnvironProvider) ConfigDefaults() schema.Defaults {
   124  	return configDefaults
   125  }
   126  
   127  func (p EnvironProvider) Validate(cfg, old *config.Config) (valid *config.Config, err error) {
   128  	// Check for valid changes for the base config values.
   129  	if err := config.Validate(cfg, old); err != nil {
   130  		return nil, err
   131  	}
   132  
   133  	validated, err := cfg.ValidateUnknownAttrs(configFields, p.Configurator.GetConfigDefaults())
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  	ecfg := &environConfig{cfg, validated}
   138  
   139  	cfgAttrs := cfg.AllAttrs()
   140  	// If we have use-openstack-gbp set to Yes we require a proper UUID for policy-target-group.
   141  	hasPTG := false
   142  	if ptg := cfgAttrs[PolicyTargetGroupKey]; ptg != nil && ptg.(string) != "" {
   143  		if utils.IsValidUUIDString(ptg.(string)) {
   144  			hasPTG = true
   145  		} else {
   146  			return nil, fmt.Errorf("policy-target-group has invalid UUID: %q", ptg)
   147  		}
   148  	}
   149  	if useGBP := cfgAttrs[UseOpenstackGBPKey]; useGBP != nil && useGBP.(bool) == true {
   150  		if hasPTG == false {
   151  			return nil, fmt.Errorf("policy-target-group must be set when use-openstack-gbp is set")
   152  		}
   153  		if network := cfgAttrs[NetworkKey]; network != nil && network.(string) != "" {
   154  			return nil, fmt.Errorf("cannot use 'network' config setting when use-openstack-gbp is set")
   155  		}
   156  	}
   157  
   158  	// Check for deprecated fields and log a warning. We also print to stderr to ensure the user sees the message
   159  	// even if they are not running with --debug.
   160  	if defaultImageId := cfgAttrs["default-image-id"]; defaultImageId != nil && defaultImageId.(string) != "" {
   161  		msg := fmt.Sprintf(
   162  			"Config attribute %q (%v) is deprecated and ignored.\n"+
   163  				"Your cloud provider should have set up image metadata to provide the correct image id\n"+
   164  				"for your chosen series and architecture. If this is a private Openstack deployment without\n"+
   165  				"existing image metadata, please run 'juju-metadata help' to see how suitable image"+
   166  				"metadata can be generated.",
   167  			"default-image-id", defaultImageId)
   168  		logger.Warningf(msg)
   169  	}
   170  	if defaultInstanceType := cfgAttrs["default-instance-type"]; defaultInstanceType != nil && defaultInstanceType.(string) != "" {
   171  		msg := fmt.Sprintf(
   172  			"Config attribute %q (%v) is deprecated and ignored.\n"+
   173  				"The correct instance flavor is determined using constraints, globally specified\n"+
   174  				"when an model is bootstrapped, or individually when a charm is deployed.\n"+
   175  				"See 'juju help bootstrap' or 'juju help deploy'.",
   176  			"default-instance-type", defaultInstanceType)
   177  		logger.Warningf(msg)
   178  	}
   179  
   180  	// Construct a new config with the deprecated attributes removed.
   181  	for _, attr := range []string{"default-image-id", "default-instance-type"} {
   182  		delete(cfgAttrs, attr)
   183  		delete(ecfg.attrs, attr)
   184  	}
   185  	for k, v := range ecfg.attrs {
   186  		cfgAttrs[k] = v
   187  	}
   188  	return config.New(config.NoDefaults, cfgAttrs)
   189  }