github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/controller/authentication/authentication.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package authentication 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/utils" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/api" 14 apiprovisioner "github.com/juju/juju/api/provisioner" 15 "github.com/juju/juju/mongo" 16 ) 17 18 // TaggedPasswordChanger defines an interface for a entity with a 19 // Tag() and SetPassword() methods. 20 type TaggedPasswordChanger interface { 21 SetPassword(string) error 22 Tag() names.Tag 23 } 24 25 // AuthenticationProvider defines the single method that the provisioner 26 // task needs to set up authentication for a machine. 27 type AuthenticationProvider interface { 28 SetupAuthentication(machine TaggedPasswordChanger) (*mongo.MongoInfo, *api.Info, error) 29 } 30 31 // NewAPIAuthenticator gets the state and api info once from the 32 // provisioner API. 33 func NewAPIAuthenticator(st *apiprovisioner.State) (AuthenticationProvider, error) { 34 stateAddresses, err := st.StateAddresses() 35 if err != nil { 36 return nil, errors.Trace(err) 37 } 38 apiAddresses, err := st.APIAddresses() 39 if err != nil { 40 return nil, errors.Trace(err) 41 } 42 caCert, err := st.CACert() 43 if err != nil { 44 return nil, errors.Trace(err) 45 } 46 modelUUID, err := st.ModelUUID() 47 if err != nil { 48 return nil, errors.Trace(err) 49 } 50 stateInfo := &mongo.MongoInfo{ 51 Info: mongo.Info{ 52 Addrs: stateAddresses, 53 CACert: caCert, 54 }, 55 } 56 apiInfo := &api.Info{ 57 Addrs: apiAddresses, 58 CACert: caCert, 59 ModelTag: names.NewModelTag(modelUUID), 60 } 61 return &simpleAuth{stateInfo, apiInfo}, nil 62 } 63 64 // SetupAuthentication generates a random password for the given machine, 65 // recording it via the machine's SetPassword method, and updates the 66 // info arguments with the tag and password. 67 func SetupAuthentication( 68 machine TaggedPasswordChanger, 69 stateInfo *mongo.MongoInfo, 70 apiInfo *api.Info, 71 ) (*mongo.MongoInfo, *api.Info, error) { 72 auth := simpleAuth{stateInfo, apiInfo} 73 return auth.SetupAuthentication(machine) 74 } 75 76 type simpleAuth struct { 77 stateInfo *mongo.MongoInfo 78 apiInfo *api.Info 79 } 80 81 func (auth *simpleAuth) SetupAuthentication(machine TaggedPasswordChanger) (*mongo.MongoInfo, *api.Info, error) { 82 password, err := utils.RandomPassword() 83 if err != nil { 84 return nil, nil, fmt.Errorf("cannot make password for machine %v: %v", machine, err) 85 } 86 if err := machine.SetPassword(password); err != nil { 87 return nil, nil, fmt.Errorf("cannot set API password for machine %v: %v", machine, err) 88 } 89 var stateInfo *mongo.MongoInfo 90 if auth.stateInfo != nil { 91 stateInfoCopy := *auth.stateInfo 92 stateInfo = &stateInfoCopy 93 stateInfo.Tag = machine.Tag() 94 stateInfo.Password = password 95 } 96 var apiInfo *api.Info 97 if auth.apiInfo != nil { 98 apiInfoCopy := *auth.apiInfo 99 apiInfo = &apiInfoCopy 100 apiInfo.Tag = machine.Tag() 101 apiInfo.Password = password 102 } 103 return stateInfo, apiInfo, nil 104 }