github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/client/instanceconfig.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package client 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/utils/set" 11 12 "github.com/juju/juju/api" 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/cloudconfig/instancecfg" 16 "github.com/juju/juju/controller/authentication" 17 "github.com/juju/juju/state" 18 ) 19 20 // InstanceConfig returns information from the environment config that 21 // is needed for machine cloud-init (for non-controllers only). It 22 // is exposed for testing purposes. 23 // TODO(rog) fix environs/manual tests so they do not need to call this, or move this elsewhere. 24 func InstanceConfig(st *state.State, machineId, nonce, dataDir string) (*instancecfg.InstanceConfig, error) { 25 environConfig, err := st.ModelConfig() 26 if err != nil { 27 return nil, errors.Annotate(err, "getting model config") 28 } 29 30 // Get the machine so we can get its series and arch. 31 // If the Arch is not set in hardware-characteristics, 32 // an error is returned. 33 machine, err := st.Machine(machineId) 34 if err != nil { 35 return nil, errors.Annotate(err, "getting machine") 36 } 37 hc, err := machine.HardwareCharacteristics() 38 if err != nil { 39 return nil, errors.Annotate(err, "getting machine hardware characteristics") 40 } 41 if hc.Arch == nil { 42 return nil, fmt.Errorf("arch is not set for %q", machine.Tag()) 43 } 44 45 // Find the appropriate tools information. 46 agentVersion, ok := environConfig.AgentVersion() 47 if !ok { 48 return nil, errors.New("no agent version set in model configuration") 49 } 50 environment, err := st.Model() 51 if err != nil { 52 return nil, errors.Annotate(err, "getting state model") 53 } 54 urlGetter := common.NewToolsURLGetter(environment.UUID(), st) 55 toolsFinder := common.NewToolsFinder(st, st, urlGetter) 56 findToolsResult, err := toolsFinder.FindTools(params.FindToolsParams{ 57 Number: agentVersion, 58 MajorVersion: -1, 59 MinorVersion: -1, 60 Series: machine.Series(), 61 Arch: *hc.Arch, 62 }) 63 if err != nil { 64 return nil, errors.Annotate(err, "finding tools") 65 } 66 if findToolsResult.Error != nil { 67 return nil, errors.Annotate(findToolsResult.Error, "finding tools") 68 } 69 toolsList := findToolsResult.List 70 71 // Get the API connection info; attempt all API addresses. 72 apiHostPorts, err := st.APIHostPorts() 73 if err != nil { 74 return nil, errors.Annotate(err, "getting API addresses") 75 } 76 apiAddrs := make(set.Strings) 77 for _, hostPorts := range apiHostPorts { 78 for _, hp := range hostPorts { 79 apiAddrs.Add(hp.NetAddr()) 80 } 81 } 82 apiInfo := &api.Info{ 83 Addrs: apiAddrs.SortedValues(), 84 CACert: st.CACert(), 85 ModelTag: st.ModelTag(), 86 } 87 88 auth := authentication.NewAuthenticator(st.MongoConnectionInfo(), apiInfo) 89 mongoInfo, apiInfo, err := auth.SetupAuthentication(machine) 90 if err != nil { 91 return nil, errors.Annotate(err, "setting up machine authentication") 92 } 93 94 // Figure out if secure connections are supported. 95 info, err := st.StateServingInfo() 96 if err != nil { 97 return nil, errors.Annotate(err, "getting state serving info") 98 } 99 secureServerConnection := info.CAPrivateKey != "" 100 icfg, err := instancecfg.NewInstanceConfig(machineId, nonce, environConfig.ImageStream(), machine.Series(), "", 101 secureServerConnection, mongoInfo, apiInfo, 102 ) 103 if err != nil { 104 return nil, errors.Annotate(err, "initializing instance config") 105 } 106 if dataDir != "" { 107 icfg.DataDir = dataDir 108 } 109 if err := icfg.SetTools(toolsList); err != nil { 110 return nil, errors.Trace(err) 111 } 112 err = instancecfg.FinishInstanceConfig(icfg, environConfig) 113 if err != nil { 114 return nil, errors.Annotate(err, "finishing instance config") 115 } 116 return icfg, nil 117 }