github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/modelcmd/credentials_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelcmd_test
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"path/filepath"
    10  
    11  	"github.com/golang/mock/gomock"
    12  	"github.com/juju/cmd/cmdtesting"
    13  	"github.com/juju/errors"
    14  	"github.com/juju/testing"
    15  	jc "github.com/juju/testing/checkers"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/cloud"
    19  	"github.com/juju/juju/cmd/modelcmd"
    20  	"github.com/juju/juju/environs"
    21  	"github.com/juju/juju/jujuclient"
    22  	_ "github.com/juju/juju/provider/dummy"
    23  )
    24  
    25  func init() {
    26  	dummyProvider, err := environs.Provider("dummy")
    27  	if err != nil {
    28  		panic(err)
    29  	}
    30  	// dummy does implement CloudEnvironProvider
    31  	asCloud := dummyProvider.(environs.CloudEnvironProvider)
    32  	environs.RegisterProvider("fake", mockProvider{asCloud})
    33  }
    34  
    35  type mockProvider struct {
    36  	environs.CloudEnvironProvider
    37  }
    38  
    39  func (mockProvider) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema {
    40  	schema := cloud.CredentialSchema{
    41  		{
    42  			"username", cloud.CredentialAttr{},
    43  		}, {
    44  			"password", cloud.CredentialAttr{},
    45  		}, {
    46  			"key", cloud.CredentialAttr{FileAttr: "key-file"},
    47  		},
    48  	}
    49  	return map[cloud.AuthType]cloud.CredentialSchema{
    50  		cloud.UserPassAuthType: schema,
    51  		"interactive": {
    52  			{"username", cloud.CredentialAttr{}},
    53  		},
    54  	}
    55  }
    56  
    57  func (mockProvider) FinalizeCredential(
    58  	ctx environs.FinalizeCredentialContext,
    59  	args environs.FinalizeCredentialParams,
    60  ) (*cloud.Credential, error) {
    61  	if args.Credential.AuthType() == "interactive" {
    62  		username := args.Credential.Attributes()["username"]
    63  		fmt.Fprintf(ctx.GetStderr(), "generating credential for %q\n", username)
    64  		out := cloud.NewCredential(cloud.UserPassAuthType, map[string]string{
    65  			"username": username,
    66  			"password": "sekret",
    67  			"key":      "value",
    68  		})
    69  		return &out, nil
    70  	}
    71  	return &args.Credential, nil
    72  }
    73  
    74  type credentialsSuite struct {
    75  	testing.IsolationSuite
    76  	cloud cloud.Cloud
    77  	store *jujuclient.MemStore
    78  }
    79  
    80  var _ = gc.Suite(&credentialsSuite{})
    81  
    82  func (s *credentialsSuite) SetUpTest(c *gc.C) {
    83  	s.IsolationSuite.SetUpTest(c)
    84  	s.cloud = cloud.Cloud{
    85  		Name: "cloud",
    86  		Type: "fake",
    87  		Regions: []cloud.Region{
    88  			{Name: "first-region"},
    89  			{Name: "second-region"},
    90  		},
    91  	}
    92  
    93  	dir := c.MkDir()
    94  	keyFile := filepath.Join(dir, "keyfile")
    95  	err := ioutil.WriteFile(keyFile, []byte("value"), 0600)
    96  	c.Assert(err, jc.ErrorIsNil)
    97  
    98  	s.store = jujuclient.NewMemStore()
    99  	s.store.Credentials["cloud"] = cloud.CloudCredential{
   100  		DefaultRegion: "second-region",
   101  		AuthCredentials: map[string]cloud.Credential{
   102  			"interactive": cloud.NewCredential("interactive", map[string]string{
   103  				"username": "user",
   104  			}),
   105  			"secrets": cloud.NewCredential(cloud.UserPassAuthType, map[string]string{
   106  				"username": "user",
   107  				"password": "sekret",
   108  				"key-file": keyFile,
   109  			}),
   110  		},
   111  	}
   112  }
   113  
   114  func (s *credentialsSuite) assertGetCredentials(c *gc.C, cred, region string) {
   115  	credential, credentialName, regionName, err := modelcmd.GetCredentials(
   116  		cmdtesting.Context(c), s.store, modelcmd.GetCredentialsParams{
   117  			Cloud:          s.cloud,
   118  			CloudRegion:    region,
   119  			CredentialName: cred,
   120  		},
   121  	)
   122  	c.Assert(err, jc.ErrorIsNil)
   123  	expectedRegion := region
   124  	if expectedRegion == "" {
   125  		expectedRegion = s.store.Credentials["cloud"].DefaultRegion
   126  	}
   127  	c.Assert(regionName, gc.Equals, expectedRegion)
   128  	c.Assert(credentialName, gc.Equals, cred)
   129  	c.Assert(credential.Attributes(), jc.DeepEquals, map[string]string{
   130  		"key":      "value",
   131  		"username": "user",
   132  		"password": "sekret",
   133  	})
   134  }
   135  
   136  func (s *credentialsSuite) TestGetCredentialsUserDefaultRegion(c *gc.C) {
   137  	s.assertGetCredentials(c, "secrets", "")
   138  }
   139  
   140  func (s *credentialsSuite) TestGetCredentialsCloudDefaultRegion(c *gc.C) {
   141  	creds := s.store.Credentials["cloud"]
   142  	creds.DefaultRegion = ""
   143  	s.store.Credentials["cloud"] = creds
   144  	s.assertGetCredentials(c, "secrets", "")
   145  }
   146  
   147  func (s *credentialsSuite) TestGetCredentialsNoRegion(c *gc.C) {
   148  	creds := s.store.Credentials["cloud"]
   149  	creds.DefaultRegion = ""
   150  	s.store.Credentials["cloud"] = creds
   151  	s.cloud.Regions = nil
   152  	s.assertGetCredentials(c, "secrets", "")
   153  }
   154  
   155  func (s *credentialsSuite) TestGetCredentials(c *gc.C) {
   156  	s.cloud.Regions = append(s.cloud.Regions, cloud.Region{Name: "third-region"})
   157  	s.assertGetCredentials(c, "secrets", "third-region")
   158  }
   159  
   160  func (s *credentialsSuite) TestGetCredentialsProviderFinalizeCredential(c *gc.C) {
   161  	s.assertGetCredentials(c, "interactive", "")
   162  }
   163  
   164  func (s *credentialsSuite) TestRegisterCredentials(c *gc.C) {
   165  	ctrl := gomock.NewController(c)
   166  	defer ctrl.Finish()
   167  
   168  	mockProvider := modelcmd.NewMockTestCloudProvider(ctrl)
   169  
   170  	credential := map[string]*cloud.CloudCredential{
   171  		"fake": {
   172  			AuthCredentials: map[string]cloud.Credential{
   173  				"admin": cloud.NewCredential("certificate", map[string]string{
   174  					"cert": "certificate",
   175  				}),
   176  			},
   177  		},
   178  	}
   179  
   180  	exp := mockProvider.EXPECT()
   181  	exp.RegisterCredentials(cloud.Cloud{
   182  		Name: "fake",
   183  	}).Return(credential, nil)
   184  
   185  	credentials, err := modelcmd.RegisterCredentials(mockProvider, modelcmd.RegisterCredentialsParams{
   186  		Cloud: cloud.Cloud{
   187  			Name: "fake",
   188  		},
   189  	})
   190  	c.Assert(err, jc.ErrorIsNil)
   191  	c.Assert(credentials, gc.DeepEquals, credential)
   192  }
   193  
   194  func (s *credentialsSuite) TestRegisterCredentialsWithNoCredentials(c *gc.C) {
   195  	ctrl := gomock.NewController(c)
   196  	defer ctrl.Finish()
   197  
   198  	mockProvider := modelcmd.NewMockTestCloudProvider(ctrl)
   199  
   200  	credential := map[string]*cloud.CloudCredential{}
   201  
   202  	exp := mockProvider.EXPECT()
   203  	exp.RegisterCredentials(cloud.Cloud{
   204  		Name: "fake",
   205  	}).Return(credential, nil)
   206  
   207  	credentials, err := modelcmd.RegisterCredentials(mockProvider, modelcmd.RegisterCredentialsParams{
   208  		Cloud: cloud.Cloud{
   209  			Name: "fake",
   210  		},
   211  	})
   212  	c.Assert(errors.Cause(err).Error(), gc.Matches, `credentials for provider not found`)
   213  	c.Assert(credentials, gc.IsNil)
   214  }
   215  
   216  func (s *credentialsSuite) TestRegisterCredentialsWithCallFailure(c *gc.C) {
   217  	ctrl := gomock.NewController(c)
   218  	defer ctrl.Finish()
   219  
   220  	mockProvider := modelcmd.NewMockTestCloudProvider(ctrl)
   221  
   222  	exp := mockProvider.EXPECT()
   223  	exp.RegisterCredentials(cloud.Cloud{
   224  		Name: "fake",
   225  	}).Return(nil, errors.New("bad"))
   226  
   227  	credentials, err := modelcmd.RegisterCredentials(mockProvider, modelcmd.RegisterCredentialsParams{
   228  		Cloud: cloud.Cloud{
   229  			Name: "fake",
   230  		},
   231  	})
   232  	c.Assert(err.Error(), gc.Matches, `registering credentials for provider: bad`)
   233  	c.Assert(credentials, gc.IsNil)
   234  }