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