github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/openstack/upgrade.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package openstack
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/errors"
    11  	"github.com/juju/version"
    12  	"gopkg.in/goose.v1/nova"
    13  )
    14  
    15  // RunUpgradeStepsFor implements provider.Upgradable
    16  func (e *Environ) RunUpgradeStepsFor(ver version.Number) error {
    17  	switch ver {
    18  	case version.Number{Major: 1, Minor: 26}:
    19  		if err := addUUIDToSecurityGroupNames(e); err != nil {
    20  			return errors.Annotate(err, "upgrading security group names in upgrade step for version 1.26")
    21  		}
    22  		if err := addUUIDToMachineNames(e); err != nil {
    23  			return errors.Annotate(err, "upgrading security machine names in upgrade step for version 1.26")
    24  		}
    25  	}
    26  	return nil
    27  }
    28  
    29  func replaceNameWithID(oldName, envName, eUUID string) (string, bool, error) {
    30  	prefix := "juju-" + envName
    31  	if !strings.HasPrefix(oldName, prefix) {
    32  		return "", false, nil
    33  	}
    34  	// This might be an env with a name that shares prefix with our current one.
    35  	if len(prefix) < len(oldName) && !strings.HasPrefix(oldName, prefix+"-") {
    36  		return "", false, nil
    37  	}
    38  	newPrefix := "juju-" + eUUID
    39  	return strings.Replace(oldName, prefix, newPrefix, -1), true, nil
    40  }
    41  
    42  func addUUIDToSecurityGroupNames(e *Environ) error {
    43  	nova := e.nova()
    44  	groups, err := nova.ListSecurityGroups()
    45  	if err != nil {
    46  		return errors.Annotate(err, "upgrading instance names")
    47  	}
    48  	cfg := e.Config()
    49  	eName := cfg.Name()
    50  	eUUID := cfg.UUID()
    51  	for _, group := range groups {
    52  		newName, ok, err := replaceNameWithID(group.Name, eName, eUUID)
    53  		if err != nil {
    54  			return errors.Annotate(err, "generating the new security group name")
    55  		}
    56  		if !ok {
    57  			continue
    58  		}
    59  		// Name should have uuid instead of name
    60  		_, err = nova.UpdateSecurityGroup(group.Id, newName, group.Description)
    61  		if err != nil {
    62  			return errors.Annotatef(err, "upgrading security group name from %q to %q", group.Name, newName)
    63  		}
    64  
    65  	}
    66  	return nil
    67  }
    68  
    69  // oldMachinesFilter returns a nova.Filter matching all machines in the environment
    70  // that use the old name schema (juju-EnvironmentName-number).
    71  func oldMachinesFilter(e *Environ) *nova.Filter {
    72  	filter := nova.NewFilter()
    73  	filter.Set(nova.FilterServer, fmt.Sprintf("juju-%s-machine-\\d*", e.Config().Name()))
    74  	return filter
    75  }
    76  
    77  func addUUIDToMachineNames(e *Environ) error {
    78  	nova := e.nova()
    79  	servers, err := nova.ListServers(oldMachinesFilter(e))
    80  	if err != nil {
    81  		return errors.Annotate(err, "upgrading server names")
    82  	}
    83  	cfg := e.Config()
    84  	eName := cfg.Name()
    85  	eUUID := cfg.UUID()
    86  	for _, server := range servers {
    87  		newName, ok, err := replaceNameWithID(server.Name, eName, eUUID)
    88  		if err != nil {
    89  			return errors.Annotate(err, "generating the new server name")
    90  		}
    91  		if !ok {
    92  			continue
    93  		}
    94  		// Name should have uuid instead of name
    95  		_, err = nova.UpdateServerName(server.Id, newName)
    96  		if err != nil {
    97  			return errors.Annotatef(err, "upgrading machine name from %q to %q", server.Name, newName)
    98  		}
    99  
   100  	}
   101  	return nil
   102  }