github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/agent/format-2.0.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package agent 5 6 import ( 7 "net" 8 "strconv" 9 10 "github.com/juju/errors" 11 "github.com/juju/version" 12 "gopkg.in/juju/names.v2" 13 goyaml "gopkg.in/yaml.v2" 14 15 "github.com/juju/juju/apiserver/params" 16 "github.com/juju/juju/state/multiwatcher" 17 ) 18 19 var format_2_0 = formatter_2_0{} 20 21 // formatter_2_0 is the formatter for the 2.0 format. 22 type formatter_2_0 struct { 23 } 24 25 // Ensure that the formatter_2_0 struct implements the formatter interface. 26 var _ formatter = formatter_2_0{} 27 28 // format_2_0Serialization holds information for a given agent. 29 type format_2_0Serialization struct { 30 Tag string `yaml:"tag,omitempty"` 31 DataDir string `yaml:"datadir,omitempty"` 32 LogDir string `yaml:"logdir,omitempty"` 33 MetricsSpoolDir string `yaml:"metricsspooldir,omitempty"` 34 Nonce string `yaml:"nonce,omitempty"` 35 Jobs []multiwatcher.MachineJob `yaml:"jobs,omitempty"` 36 UpgradedToVersion *version.Number `yaml:"upgradedToVersion"` 37 38 CACert string `yaml:"cacert,omitempty"` 39 StateAddresses []string `yaml:"stateaddresses,omitempty"` 40 StatePassword string `yaml:"statepassword,omitempty"` 41 42 Controller string `yaml:"controller,omitempty"` 43 Model string `yaml:"model,omitempty"` 44 APIAddresses []string `yaml:"apiaddresses,omitempty"` 45 APIPassword string `yaml:"apipassword,omitempty"` 46 47 OldPassword string `yaml:"oldpassword,omitempty"` 48 Values map[string]string `yaml:"values"` 49 50 // Only controller machines have these next items set. 51 ControllerCert string `yaml:"controllercert,omitempty"` 52 ControllerKey string `yaml:"controllerkey,omitempty"` 53 CAPrivateKey string `yaml:"caprivatekey,omitempty"` 54 APIPort int `yaml:"apiport,omitempty"` 55 StatePort int `yaml:"stateport,omitempty"` 56 SharedSecret string `yaml:"sharedsecret,omitempty"` 57 SystemIdentity string `yaml:"systemidentity,omitempty"` 58 MongoVersion string `yaml:"mongoversion,omitempty"` 59 } 60 61 func init() { 62 registerFormat(format_2_0) 63 } 64 65 func (formatter_2_0) version() string { 66 return "2.0" 67 } 68 69 func (formatter_2_0) unmarshal(data []byte) (*configInternal, error) { 70 // NOTE: this needs to handle the absence of StatePort and get it from the 71 // address 72 var format format_2_0Serialization 73 if err := goyaml.Unmarshal(data, &format); err != nil { 74 return nil, err 75 } 76 tag, err := names.ParseTag(format.Tag) 77 if err != nil { 78 return nil, err 79 } 80 controllerTag, err := names.ParseControllerTag(format.Controller) 81 if err != nil { 82 return nil, errors.Trace(err) 83 } 84 modelTag, err := names.ParseModelTag(format.Model) 85 if err != nil { 86 return nil, errors.Trace(err) 87 } 88 config := &configInternal{ 89 tag: tag, 90 paths: NewPathsWithDefaults(Paths{ 91 DataDir: format.DataDir, 92 LogDir: format.LogDir, 93 MetricsSpoolDir: format.MetricsSpoolDir, 94 }), 95 jobs: format.Jobs, 96 upgradedToVersion: *format.UpgradedToVersion, 97 nonce: format.Nonce, 98 controller: controllerTag, 99 model: modelTag, 100 caCert: format.CACert, 101 oldPassword: format.OldPassword, 102 values: format.Values, 103 } 104 if len(format.StateAddresses) > 0 { 105 config.stateDetails = &connectionDetails{ 106 format.StateAddresses, 107 format.StatePassword, 108 } 109 } 110 if len(format.APIAddresses) > 0 { 111 config.apiDetails = &connectionDetails{ 112 format.APIAddresses, 113 format.APIPassword, 114 } 115 } 116 if len(format.ControllerKey) != 0 { 117 config.servingInfo = ¶ms.StateServingInfo{ 118 Cert: format.ControllerCert, 119 PrivateKey: format.ControllerKey, 120 CAPrivateKey: format.CAPrivateKey, 121 APIPort: format.APIPort, 122 StatePort: format.StatePort, 123 SharedSecret: format.SharedSecret, 124 SystemIdentity: format.SystemIdentity, 125 } 126 // If private key is not present, infer it from the ports in the state addresses. 127 if config.servingInfo.StatePort == 0 { 128 if len(format.StateAddresses) == 0 { 129 return nil, errors.New("server key found but no state port") 130 } 131 132 _, portString, err := net.SplitHostPort(format.StateAddresses[0]) 133 if err != nil { 134 return nil, err 135 } 136 statePort, err := strconv.Atoi(portString) 137 if err != nil { 138 return nil, err 139 } 140 config.servingInfo.StatePort = statePort 141 } 142 143 } 144 145 // TODO (anastasiamac 2016-06-17) Mongo version must be set. 146 // For scenarios where mongo version is not set, we should still 147 // be explicit about what "default" mongo version is. After these lines, 148 // config.mongoVersion should not be empty under any circumstance. 149 // Bug# 1593855 150 if format.MongoVersion != "" { 151 // Mongo version is set, we might be running a version other than default. 152 config.mongoVersion = format.MongoVersion 153 } 154 return config, nil 155 } 156 157 func (formatter_2_0) marshal(config *configInternal) ([]byte, error) { 158 controllerTag := config.controller.String() 159 modelTag := config.model.String() 160 format := &format_2_0Serialization{ 161 Tag: config.tag.String(), 162 DataDir: config.paths.DataDir, 163 LogDir: config.paths.LogDir, 164 MetricsSpoolDir: config.paths.MetricsSpoolDir, 165 Jobs: config.jobs, 166 UpgradedToVersion: &config.upgradedToVersion, 167 Nonce: config.nonce, 168 Controller: controllerTag, 169 Model: modelTag, 170 CACert: string(config.caCert), 171 OldPassword: config.oldPassword, 172 Values: config.values, 173 } 174 if config.servingInfo != nil { 175 format.ControllerCert = config.servingInfo.Cert 176 format.ControllerKey = config.servingInfo.PrivateKey 177 format.CAPrivateKey = config.servingInfo.CAPrivateKey 178 format.APIPort = config.servingInfo.APIPort 179 format.StatePort = config.servingInfo.StatePort 180 format.SharedSecret = config.servingInfo.SharedSecret 181 format.SystemIdentity = config.servingInfo.SystemIdentity 182 } 183 if config.stateDetails != nil { 184 if len(config.stateDetails.addresses) > 0 { 185 format.StateAddresses = config.stateDetails.addresses 186 format.StatePassword = config.stateDetails.password 187 } 188 } 189 if config.apiDetails != nil { 190 if len(config.apiDetails.addresses) > 0 { 191 format.APIAddresses = config.apiDetails.addresses 192 format.APIPassword = config.apiDetails.password 193 } 194 } 195 if config.mongoVersion != "" { 196 format.MongoVersion = string(config.mongoVersion) 197 } 198 return goyaml.Marshal(format) 199 }