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 = &params.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  }