github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/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  	goyaml "gopkg.in/yaml.v1"
    14  
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/state/multiwatcher"
    17  	"github.com/juju/juju/version"
    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  	Nonce             string
    35  	Jobs              []multiwatcher.MachineJob `yaml:",omitempty"`
    36  	UpgradedToVersion *version.Number           `yaml:"upgradedToVersion"`
    37  
    38  	CACert         string
    39  	StateAddresses []string `yaml:",omitempty"`
    40  	StatePassword  string   `yaml:",omitempty"`
    41  
    42  	Environment  string   `yaml:",omitempty"`
    43  	APIAddresses []string `yaml:",omitempty"`
    44  	APIPassword  string   `yaml:",omitempty"`
    45  
    46  	OldPassword string
    47  	Values      map[string]string
    48  
    49  	PreferIPv6 bool `yaml:"prefer-ipv6,omitempty"`
    50  
    51  	// Only state server machines have these next items set.
    52  	StateServerCert string `yaml:",omitempty"`
    53  	StateServerKey  string `yaml:",omitempty"`
    54  	CAPrivateKey    string `yaml:",omitempty"`
    55  	APIPort         int    `yaml:",omitempty"`
    56  	StatePort       int    `yaml:",omitempty"`
    57  	SharedSecret    string `yaml:",omitempty"`
    58  	SystemIdentity  string `yaml:",omitempty"`
    59  }
    60  
    61  func init() {
    62  	registerFormat(format_1_18)
    63  }
    64  
    65  func (formatter_1_18) version() string {
    66  	return "1.18"
    67  }
    68  
    69  func (formatter_1_18) 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_1_18Serialization
    73  	if err := goyaml.Unmarshal(data, &format); err != nil {
    74  		return nil, err
    75  	}
    76  	if format.UpgradedToVersion == nil || *format.UpgradedToVersion == version.Zero {
    77  		// Assume we upgrade from 1.16.
    78  		upgradedToVersion := version.MustParse("1.16.0")
    79  		format.UpgradedToVersion = &upgradedToVersion
    80  	}
    81  	tag, err := names.ParseTag(format.Tag)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	var envTag names.EnvironTag
    86  	if format.Environment != "" {
    87  		envTag, err = names.ParseEnvironTag(format.Environment)
    88  		if err != nil {
    89  			return nil, errors.Trace(err)
    90  		}
    91  	}
    92  	config := &configInternal{
    93  		tag:               tag,
    94  		dataDir:           format.DataDir,
    95  		logDir:            format.LogDir,
    96  		jobs:              format.Jobs,
    97  		upgradedToVersion: *format.UpgradedToVersion,
    98  		nonce:             format.Nonce,
    99  		environment:       envTag,
   100  		caCert:            format.CACert,
   101  		oldPassword:       format.OldPassword,
   102  		values:            format.Values,
   103  		preferIPv6:        format.PreferIPv6,
   104  	}
   105  	if config.logDir == "" {
   106  		config.logDir = DefaultLogDir
   107  	}
   108  	if config.dataDir == "" {
   109  		config.dataDir = DefaultDataDir
   110  	}
   111  	if len(format.StateAddresses) > 0 {
   112  		config.stateDetails = &connectionDetails{
   113  			format.StateAddresses,
   114  			format.StatePassword,
   115  		}
   116  	}
   117  	if len(format.APIAddresses) > 0 {
   118  		config.apiDetails = &connectionDetails{
   119  			format.APIAddresses,
   120  			format.APIPassword,
   121  		}
   122  	}
   123  	if len(format.StateServerKey) != 0 {
   124  		config.servingInfo = &params.StateServingInfo{
   125  			Cert:           format.StateServerCert,
   126  			PrivateKey:     format.StateServerKey,
   127  			CAPrivateKey:   format.CAPrivateKey,
   128  			APIPort:        format.APIPort,
   129  			StatePort:      format.StatePort,
   130  			SharedSecret:   format.SharedSecret,
   131  			SystemIdentity: format.SystemIdentity,
   132  		}
   133  		// There's a private key, then we need the state port,
   134  		// which wasn't always in the  1.18 format. If it's not present
   135  		// we can infer it from the ports in the state addresses.
   136  		if config.servingInfo.StatePort == 0 {
   137  			if len(format.StateAddresses) == 0 {
   138  				return nil, fmt.Errorf("server key found but no state port")
   139  			}
   140  
   141  			_, portString, err := net.SplitHostPort(format.StateAddresses[0])
   142  			if err != nil {
   143  				return nil, err
   144  			}
   145  			statePort, err := strconv.Atoi(portString)
   146  			if err != nil {
   147  				return nil, err
   148  			}
   149  			config.servingInfo.StatePort = statePort
   150  		}
   151  
   152  	}
   153  	return config, nil
   154  }
   155  
   156  func (formatter_1_18) marshal(config *configInternal) ([]byte, error) {
   157  	var envTag string
   158  	if config.environment.Id() != "" {
   159  		envTag = config.environment.String()
   160  	}
   161  	format := &format_1_18Serialization{
   162  		Tag:               config.tag.String(),
   163  		DataDir:           config.dataDir,
   164  		LogDir:            config.logDir,
   165  		Jobs:              config.jobs,
   166  		UpgradedToVersion: &config.upgradedToVersion,
   167  		Nonce:             config.nonce,
   168  		Environment:       envTag,
   169  		CACert:            string(config.caCert),
   170  		OldPassword:       config.oldPassword,
   171  		Values:            config.values,
   172  		PreferIPv6:        config.preferIPv6,
   173  	}
   174  	if config.servingInfo != nil {
   175  		format.StateServerCert = config.servingInfo.Cert
   176  		format.StateServerKey = 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  		format.StateAddresses = config.stateDetails.addresses
   185  		format.StatePassword = config.stateDetails.password
   186  	}
   187  	if config.apiDetails != nil {
   188  		format.APIAddresses = config.apiDetails.addresses
   189  		format.APIPassword = config.apiDetails.password
   190  	}
   191  	return goyaml.Marshal(format)
   192  }