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

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cloudspec_test
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/juju/names/v5"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	"github.com/juju/utils/v3"
    13  	gc "gopkg.in/check.v1"
    14  
    15  	"github.com/juju/juju/apiserver/common"
    16  	"github.com/juju/juju/apiserver/common/cloudspec"
    17  	apiservertesting "github.com/juju/juju/apiserver/testing"
    18  	"github.com/juju/juju/cloud"
    19  	environscloudspec "github.com/juju/juju/environs/cloudspec"
    20  	"github.com/juju/juju/rpc/params"
    21  	"github.com/juju/juju/state"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  type CloudSpecSuite struct {
    26  	testing.IsolationSuite
    27  	testing.Stub
    28  	result   environscloudspec.CloudSpec
    29  	authFunc common.AuthFunc
    30  	api      cloudspec.CloudSpecAPI
    31  }
    32  
    33  var _ = gc.Suite(&CloudSpecSuite{})
    34  
    35  func (s *CloudSpecSuite) SetUpTest(c *gc.C) {
    36  	s.IsolationSuite.SetUpTest(c)
    37  	s.Stub.ResetCalls()
    38  
    39  	s.authFunc = func(tag names.Tag) bool {
    40  		s.AddCall("Auth", tag)
    41  		return tag == coretesting.ModelTag
    42  	}
    43  	s.api = s.getTestCloudSpec(apiservertesting.NewFakeNotifyWatcher())
    44  	credential := cloud.NewCredential(
    45  		"auth-type",
    46  		map[string]string{"k": "v"},
    47  	)
    48  	s.result = environscloudspec.CloudSpec{
    49  		Type:             "type",
    50  		Name:             "name",
    51  		Region:           "region",
    52  		Endpoint:         "endpoint",
    53  		IdentityEndpoint: "identity-endpoint",
    54  		StorageEndpoint:  "storage-endpoint",
    55  		Credential:       &credential,
    56  		CACertificates:   []string{coretesting.CACert},
    57  		SkipTLSVerify:    true,
    58  	}
    59  }
    60  
    61  func (s *CloudSpecSuite) getTestCloudSpec(credentialContentWatcher state.NotifyWatcher) cloudspec.CloudSpecAPI {
    62  	return cloudspec.NewCloudSpec(
    63  		common.NewResources(),
    64  		func(tag names.ModelTag) (environscloudspec.CloudSpec, error) {
    65  			s.AddCall("CloudSpec", tag)
    66  			return s.result, s.NextErr()
    67  		},
    68  		func(tag names.ModelTag) (state.NotifyWatcher, error) {
    69  			s.AddCall("WatchCloudSpec", tag)
    70  			return apiservertesting.NewFakeNotifyWatcher(), s.NextErr()
    71  		},
    72  		func(tag names.ModelTag) (state.NotifyWatcher, error) {
    73  			s.AddCall("WatchCredentialReference", tag)
    74  			return apiservertesting.NewFakeNotifyWatcher(), s.NextErr()
    75  		},
    76  		func(tag names.ModelTag) (state.NotifyWatcher, error) {
    77  			s.AddCall("WatchCredentialContent", tag)
    78  			return credentialContentWatcher, s.NextErr()
    79  		},
    80  		func() (common.AuthFunc, error) {
    81  			s.AddCall("GetAuthFunc")
    82  			return s.authFunc, s.NextErr()
    83  		})
    84  }
    85  
    86  func (s *CloudSpecSuite) TestCloudSpec(c *gc.C) {
    87  	otherModelTag := names.NewModelTag(utils.MustNewUUID().String())
    88  	machineTag := names.NewMachineTag("42")
    89  	result, err := s.api.CloudSpec(params.Entities{Entities: []params.Entity{
    90  		{coretesting.ModelTag.String()},
    91  		{otherModelTag.String()},
    92  		{machineTag.String()},
    93  	}})
    94  	c.Assert(err, jc.ErrorIsNil)
    95  	c.Assert(result.Results, jc.DeepEquals, []params.CloudSpecResult{{
    96  		Result: &params.CloudSpec{
    97  			Type:             "type",
    98  			Name:             "name",
    99  			Region:           "region",
   100  			Endpoint:         "endpoint",
   101  			IdentityEndpoint: "identity-endpoint",
   102  			StorageEndpoint:  "storage-endpoint",
   103  			Credential: &params.CloudCredential{
   104  				AuthType:   "auth-type",
   105  				Attributes: map[string]string{"k": "v"},
   106  			},
   107  			CACertificates: []string{coretesting.CACert},
   108  			SkipTLSVerify:  true,
   109  		},
   110  	}, {
   111  		Error: &params.Error{
   112  			Code:    params.CodeUnauthorized,
   113  			Message: "permission denied",
   114  		},
   115  	}, {
   116  		Error: &params.Error{
   117  			Message: `"machine-42" is not a valid model tag`,
   118  		},
   119  	}})
   120  	s.CheckCalls(c, []testing.StubCall{
   121  		{"GetAuthFunc", nil},
   122  		{"Auth", []interface{}{coretesting.ModelTag}},
   123  		{"CloudSpec", []interface{}{coretesting.ModelTag}},
   124  		{"Auth", []interface{}{otherModelTag}},
   125  	})
   126  }
   127  
   128  func (s *CloudSpecSuite) TestWatchCloudSpecsChanges(c *gc.C) {
   129  	otherModelTag := names.NewModelTag(utils.MustNewUUID().String())
   130  	machineTag := names.NewMachineTag("42")
   131  	result, err := s.api.WatchCloudSpecsChanges(params.Entities{Entities: []params.Entity{
   132  		{coretesting.ModelTag.String()},
   133  		{otherModelTag.String()},
   134  		{machineTag.String()},
   135  	}})
   136  	c.Assert(err, jc.ErrorIsNil)
   137  	c.Assert(result.Results, jc.DeepEquals, []params.NotifyWatchResult{{
   138  		NotifyWatcherId: "1",
   139  	}, {
   140  		Error: &params.Error{
   141  			Code:    params.CodeUnauthorized,
   142  			Message: "permission denied",
   143  		},
   144  	}, {
   145  		Error: &params.Error{
   146  			Message: `"machine-42" is not a valid model tag`,
   147  		},
   148  	}})
   149  	s.CheckCalls(c, []testing.StubCall{
   150  		{"GetAuthFunc", nil},
   151  		{"Auth", []interface{}{coretesting.ModelTag}},
   152  		{"WatchCloudSpec", []interface{}{coretesting.ModelTag}},
   153  		{"WatchCredentialReference", []interface{}{coretesting.ModelTag}},
   154  		{"WatchCredentialContent", []interface{}{coretesting.ModelTag}},
   155  		{"Auth", []interface{}{otherModelTag}},
   156  	})
   157  }
   158  
   159  func (s *CloudSpecSuite) TestWatchCloudSpecsNoCredentialContentToWatch(c *gc.C) {
   160  	s.api = s.getTestCloudSpec(nil)
   161  	result, err := s.api.WatchCloudSpecsChanges(params.Entities{Entities: []params.Entity{
   162  		{coretesting.ModelTag.String()},
   163  	}})
   164  	c.Assert(err, jc.ErrorIsNil)
   165  	c.Assert(result.Results, jc.DeepEquals, []params.NotifyWatchResult{{
   166  		NotifyWatcherId: "1",
   167  	}})
   168  	s.CheckCalls(c, []testing.StubCall{
   169  		{"GetAuthFunc", nil},
   170  		{"Auth", []interface{}{coretesting.ModelTag}},
   171  		{"WatchCloudSpec", []interface{}{coretesting.ModelTag}},
   172  		{"WatchCredentialReference", []interface{}{coretesting.ModelTag}},
   173  		{"WatchCredentialContent", []interface{}{coretesting.ModelTag}},
   174  	})
   175  }
   176  
   177  func (s *CloudSpecSuite) TestCloudSpecNilCredential(c *gc.C) {
   178  	s.result.Credential = nil
   179  	result, err := s.api.CloudSpec(params.Entities{
   180  		Entities: []params.Entity{{coretesting.ModelTag.String()}},
   181  	})
   182  	c.Assert(err, jc.ErrorIsNil)
   183  	c.Assert(result.Results, jc.DeepEquals, []params.CloudSpecResult{{
   184  		Result: &params.CloudSpec{
   185  			Type:             "type",
   186  			Name:             "name",
   187  			Region:           "region",
   188  			Endpoint:         "endpoint",
   189  			IdentityEndpoint: "identity-endpoint",
   190  			StorageEndpoint:  "storage-endpoint",
   191  			Credential:       nil,
   192  			CACertificates:   []string{coretesting.CACert},
   193  			SkipTLSVerify:    true,
   194  		},
   195  	}})
   196  }
   197  
   198  func (s *CloudSpecSuite) TestCloudSpecGetAuthFuncError(c *gc.C) {
   199  	expect := errors.New("bewm")
   200  	s.SetErrors(expect)
   201  	result, err := s.api.CloudSpec(params.Entities{
   202  		Entities: []params.Entity{{coretesting.ModelTag.String()}},
   203  	})
   204  	c.Assert(err, gc.Equals, expect)
   205  	c.Assert(result, jc.DeepEquals, params.CloudSpecResults{})
   206  }
   207  
   208  func (s *CloudSpecSuite) TestCloudSpecCloudSpecError(c *gc.C) {
   209  	s.SetErrors(nil, errors.New("bewm"))
   210  	result, err := s.api.CloudSpec(params.Entities{
   211  		Entities: []params.Entity{{coretesting.ModelTag.String()}},
   212  	})
   213  	c.Assert(err, jc.ErrorIsNil)
   214  	c.Assert(result, jc.DeepEquals, params.CloudSpecResults{Results: []params.CloudSpecResult{{
   215  		Error: &params.Error{Message: "bewm"},
   216  	}}})
   217  }