github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/agent/format-1.18.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 "fmt" 8 "net" 9 "strconv" 10 11 "github.com/juju/errors" 12 "github.com/juju/names" 13 "github.com/juju/version" 14 goyaml "gopkg.in/yaml.v2" 15 16 "github.com/juju/juju/apiserver/params" 17 "github.com/juju/juju/state/multiwatcher" 18 ) 19 20 var format_1_18 = formatter_1_18{} 21 22 // formatter_1_18 is the formatter for the 1.18 format. 23 type formatter_1_18 struct { 24 } 25 26 // Ensure that the formatter_1_18 struct implements the formatter interface. 27 var _ formatter = formatter_1_18{} 28 29 // format_1_18Serialization holds information for a given agent. 30 type format_1_18Serialization struct { 31 Tag string 32 DataDir string 33 LogDir string 34 MetricsSpoolDir string 35 Nonce string 36 Jobs []multiwatcher.MachineJob `yaml:",omitempty"` 37 UpgradedToVersion *version.Number `yaml:"upgradedToVersion"` 38 39 CACert string 40 StateAddresses []string `yaml:",omitempty"` 41 StatePassword string `yaml:",omitempty"` 42 43 Model string `yaml:",omitempty"` 44 APIAddresses []string `yaml:",omitempty"` 45 APIPassword string `yaml:",omitempty"` 46 47 OldPassword string 48 Values map[string]string 49 50 PreferIPv6 bool `yaml:"prefer-ipv6,omitempty"` 51 52 // Only controller machines have these next items set. 53 ControllerCert string `yaml:",omitempty"` 54 ControllerKey string `yaml:",omitempty"` 55 CAPrivateKey string `yaml:",omitempty"` 56 APIPort int `yaml:",omitempty"` 57 StatePort int `yaml:",omitempty"` 58 SharedSecret string `yaml:",omitempty"` 59 SystemIdentity string `yaml:",omitempty"` 60 MongoVersion string `yaml:",omitempty"` 61 } 62 63 func init() { 64 registerFormat(format_1_18) 65 } 66 67 func (formatter_1_18) version() string { 68 return "1.18" 69 } 70 71 func (formatter_1_18) unmarshal(data []byte) (*configInternal, error) { 72 // NOTE: this needs to handle the absence of StatePort and get it from the 73 // address 74 var format format_1_18Serialization 75 if err := goyaml.Unmarshal(data, &format); err != nil { 76 return nil, err 77 } 78 if format.UpgradedToVersion == nil || *format.UpgradedToVersion == version.Zero { 79 // Assume we upgrade from 1.16. 80 upgradedToVersion := version.MustParse("1.16.0") 81 format.UpgradedToVersion = &upgradedToVersion 82 } 83 tag, err := names.ParseTag(format.Tag) 84 if err != nil { 85 return nil, err 86 } 87 var modelTag names.ModelTag 88 if format.Model != "" { 89 modelTag, err = names.ParseModelTag(format.Model) 90 if err != nil { 91 return nil, errors.Trace(err) 92 } 93 } 94 config := &configInternal{ 95 tag: tag, 96 paths: NewPathsWithDefaults(Paths{ 97 DataDir: format.DataDir, 98 LogDir: format.LogDir, 99 MetricsSpoolDir: format.MetricsSpoolDir, 100 }), 101 jobs: format.Jobs, 102 upgradedToVersion: *format.UpgradedToVersion, 103 nonce: format.Nonce, 104 model: modelTag, 105 caCert: format.CACert, 106 oldPassword: format.OldPassword, 107 values: format.Values, 108 preferIPv6: format.PreferIPv6, 109 } 110 if len(format.StateAddresses) > 0 { 111 config.stateDetails = &connectionDetails{ 112 format.StateAddresses, 113 format.StatePassword, 114 } 115 } 116 if len(format.APIAddresses) > 0 { 117 config.apiDetails = &connectionDetails{ 118 format.APIAddresses, 119 format.APIPassword, 120 } 121 } 122 if len(format.ControllerKey) != 0 { 123 config.servingInfo = ¶ms.StateServingInfo{ 124 Cert: format.ControllerCert, 125 PrivateKey: format.ControllerKey, 126 CAPrivateKey: format.CAPrivateKey, 127 APIPort: format.APIPort, 128 StatePort: format.StatePort, 129 SharedSecret: format.SharedSecret, 130 SystemIdentity: format.SystemIdentity, 131 } 132 // There's a private key, then we need the state port, 133 // which wasn't always in the 1.18 format. If it's not present 134 // we can infer it from the ports in the state addresses. 135 if config.servingInfo.StatePort == 0 { 136 if len(format.StateAddresses) == 0 { 137 return nil, fmt.Errorf("server key found but no state port") 138 } 139 140 _, portString, err := net.SplitHostPort(format.StateAddresses[0]) 141 if err != nil { 142 return nil, err 143 } 144 statePort, err := strconv.Atoi(portString) 145 if err != nil { 146 return nil, err 147 } 148 config.servingInfo.StatePort = statePort 149 } 150 151 } 152 // Mongo version is set, we might be running a version other than default. 153 if format.MongoVersion != "" { 154 config.mongoVersion = format.MongoVersion 155 } 156 return config, nil 157 } 158 159 func (formatter_1_18) marshal(config *configInternal) ([]byte, error) { 160 var modelTag string 161 if config.model.Id() != "" { 162 modelTag = config.model.String() 163 } 164 format := &format_1_18Serialization{ 165 Tag: config.tag.String(), 166 DataDir: config.paths.DataDir, 167 LogDir: config.paths.LogDir, 168 MetricsSpoolDir: config.paths.MetricsSpoolDir, 169 Jobs: config.jobs, 170 UpgradedToVersion: &config.upgradedToVersion, 171 Nonce: config.nonce, 172 Model: modelTag, 173 CACert: string(config.caCert), 174 OldPassword: config.oldPassword, 175 Values: config.values, 176 PreferIPv6: config.preferIPv6, 177 } 178 if config.servingInfo != nil { 179 format.ControllerCert = config.servingInfo.Cert 180 format.ControllerKey = config.servingInfo.PrivateKey 181 format.CAPrivateKey = config.servingInfo.CAPrivateKey 182 format.APIPort = config.servingInfo.APIPort 183 format.StatePort = config.servingInfo.StatePort 184 format.SharedSecret = config.servingInfo.SharedSecret 185 format.SystemIdentity = config.servingInfo.SystemIdentity 186 } 187 if config.stateDetails != nil { 188 format.StateAddresses = config.stateDetails.addresses 189 format.StatePassword = config.stateDetails.password 190 } 191 if config.apiDetails != nil { 192 format.APIAddresses = config.apiDetails.addresses 193 format.APIPassword = config.apiDetails.password 194 } 195 if config.mongoVersion != "" { 196 format.MongoVersion = string(config.mongoVersion) 197 } 198 return goyaml.Marshal(format) 199 }