github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/environs/cloudspec/cloudspec.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cloudspec
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names/v5"
     9  
    10  	jujucloud "github.com/juju/juju/cloud"
    11  )
    12  
    13  // CloudSpec describes a specific cloud configuration, for the purpose
    14  // of opening an Environ to manage the cloud resources.
    15  type CloudSpec struct {
    16  	// Type is the type of cloud, eg aws, openstack etc.
    17  	Type string
    18  
    19  	// Name is the name of the cloud.
    20  	Name string
    21  
    22  	// Region is the name of the cloud region, if the cloud supports
    23  	// regions.
    24  	Region string
    25  
    26  	// Endpoint is the endpoint for the cloud (region).
    27  	Endpoint string
    28  
    29  	// IdentityEndpoint is the identity endpoint for the cloud (region).
    30  	IdentityEndpoint string
    31  
    32  	// StorageEndpoint is the storage endpoint for the cloud (region).
    33  	StorageEndpoint string
    34  
    35  	// Credential is the cloud credential to use to authenticate
    36  	// with the cloud, or nil if the cloud does not require any
    37  	// credentials.
    38  	Credential *jujucloud.Credential
    39  
    40  	// CACertificates contains an optional list of Certificate
    41  	// Authority certificates to be used to validate certificates
    42  	// of cloud infrastructure components
    43  	// The contents are Base64 encoded x.509 certs.
    44  	CACertificates []string
    45  
    46  	// SkipTLSVerify is true if the client should be asked not to
    47  	// validate certificates. It is not recommended for production clouds.
    48  	// It is secure (false) by default.
    49  	SkipTLSVerify bool
    50  
    51  	// IsControllerCloud is true when this is the cloud used by the controller.
    52  	IsControllerCloud bool
    53  }
    54  
    55  // Validate validates that the CloudSpec is well-formed. It does
    56  // not ensure that the cloud type and credentials are valid.
    57  func (cs CloudSpec) Validate() error {
    58  	if cs.Type == "" {
    59  		return errors.NotValidf("empty Type")
    60  	}
    61  	if !names.IsValidCloud(cs.Name) {
    62  		return errors.NotValidf("cloud name %q", cs.Name)
    63  	}
    64  	return nil
    65  }
    66  
    67  // MakeCloudSpec returns a CloudSpec from the given
    68  // Cloud, cloud and region names, and credential.
    69  func MakeCloudSpec(cloud jujucloud.Cloud, cloudRegionName string, credential *jujucloud.Credential) (CloudSpec, error) {
    70  	cloudSpec := CloudSpec{
    71  		Type:              cloud.Type,
    72  		Name:              cloud.Name,
    73  		Region:            cloudRegionName,
    74  		Endpoint:          cloud.Endpoint,
    75  		IdentityEndpoint:  cloud.IdentityEndpoint,
    76  		StorageEndpoint:   cloud.StorageEndpoint,
    77  		CACertificates:    cloud.CACertificates,
    78  		SkipTLSVerify:     cloud.SkipTLSVerify,
    79  		Credential:        credential,
    80  		IsControllerCloud: cloud.IsControllerCloud,
    81  	}
    82  	if cloudRegionName != "" {
    83  		cloudRegion, err := jujucloud.RegionByName(cloud.Regions, cloudRegionName)
    84  		if err != nil {
    85  			return CloudSpec{}, errors.Annotate(err, "getting cloud region definition")
    86  		}
    87  		if !cloudRegion.IsEmpty() {
    88  			cloudSpec.Endpoint = cloudRegion.Endpoint
    89  			cloudSpec.IdentityEndpoint = cloudRegion.IdentityEndpoint
    90  			cloudSpec.StorageEndpoint = cloudRegion.StorageEndpoint
    91  		}
    92  	}
    93  	return cloudSpec, nil
    94  }
    95  
    96  // CloudRegionSpec contains the information needed to lookup specific
    97  // cloud or cloud region configuration. This is for use in calling
    98  // state/modelconfig.(ComposeNewModelConfig) so there is no need to serialize it.
    99  type CloudRegionSpec struct {
   100  	// Cloud is the name of the cloud.
   101  	Cloud string
   102  
   103  	// Region is the name of the cloud region.
   104  	Region string
   105  }
   106  
   107  // NewCloudRegionSpec returns a CloudRegionSpec ensuring cloud arg is not empty.
   108  func NewCloudRegionSpec(cloud, region string) (*CloudRegionSpec, error) {
   109  	if cloud == "" {
   110  		return nil, errors.New("cloud is required to be non empty")
   111  	}
   112  	return &CloudRegionSpec{Cloud: cloud, Region: region}, nil
   113  }