зеркало из https://github.com/Azure/acs-engine.git
orchestrator upgrade: use ContainerService's OrchestratorProfile as a GoalState (#1407)
* eliminated duplicated structures * added run-time check for upgradable clusters * updated k8sUpgrade.json * replaced proprietary implementation of orch. versions with semver package * updated API loader for the upgrade operation in ContainerService * added pre-validation for the upgrade * removed experimental flag from the upgrade operation * deleted redundant UpgradeContainerService. Use OrchestratorProfile instead
This commit is contained in:
Родитель
95dca7c7e3
Коммит
4e734f08d4
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/acsengine"
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -40,7 +40,7 @@ func newOrchestratorsCmd() *cobra.Command {
|
|||
}
|
||||
|
||||
func (oc *orchestratorsCmd) run(cmd *cobra.Command, args []string) error {
|
||||
orchs, err := acsengine.GetOrchestratorVersionProfileList(oc.orchestrator, oc.release)
|
||||
orchs, err := api.GetOrchestratorVersionProfileList(oc.orchestrator, oc.release)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/armhelpers"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
@ -42,10 +40,7 @@ func NewRootCmd() *cobra.Command {
|
|||
rootCmd.AddCommand(newGenerateCmd())
|
||||
rootCmd.AddCommand(newDeployCmd())
|
||||
rootCmd.AddCommand(newOrchestratorsCmd())
|
||||
|
||||
if val := os.Getenv("ACSENGINE_EXPERIMENTAL_FEATURES"); val == "1" {
|
||||
rootCmd.AddCommand(newUpgradeCmd())
|
||||
}
|
||||
rootCmd.AddCommand(newUpgradeCmd())
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"path"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
"github.com/Azure/acs-engine/pkg/api/vlabs"
|
||||
"github.com/Azure/acs-engine/pkg/armhelpers"
|
||||
"github.com/Azure/acs-engine/pkg/i18n"
|
||||
"github.com/Azure/acs-engine/pkg/operations/kubernetesupgrade"
|
||||
|
@ -34,11 +35,9 @@ type upgradeCmd struct {
|
|||
apiVersion string
|
||||
|
||||
// derived
|
||||
upgradeContainerService *api.UpgradeContainerService
|
||||
upgradeAPIVersion string
|
||||
client armhelpers.ACSEngineClient
|
||||
locale *gotext.Locale
|
||||
nameSuffix string
|
||||
client armhelpers.ACSEngineClient
|
||||
locale *gotext.Locale
|
||||
nameSuffix string
|
||||
}
|
||||
|
||||
// NewUpgradeCmd run a command to upgrade a Kubernetes cluster
|
||||
|
@ -96,7 +95,7 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {
|
|||
// load apimodel from the deployment directory
|
||||
apiModelPath := path.Join(uc.deploymentDirectory, "apimodel.json")
|
||||
|
||||
if _, err := os.Stat(apiModelPath); os.IsNotExist(err) {
|
||||
if _, err = os.Stat(apiModelPath); os.IsNotExist(err) {
|
||||
log.Fatalf("specified api model does not exist (%s)", apiModelPath)
|
||||
}
|
||||
|
||||
|
@ -109,19 +108,17 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {
|
|||
if err != nil {
|
||||
log.Fatalf("error parsing the api model: %s", err.Error())
|
||||
}
|
||||
|
||||
if _, err := os.Stat(uc.upgradeModelFile); os.IsNotExist(err) {
|
||||
if _, err = os.Stat(uc.upgradeModelFile); os.IsNotExist(err) {
|
||||
log.Fatalf("specified upgrade model file does not exist (%s)", uc.upgradeModelFile)
|
||||
}
|
||||
|
||||
upgradeapiloader := &api.UpgradeApiloader{
|
||||
Translator: &i18n.Translator{
|
||||
Locale: uc.locale,
|
||||
},
|
||||
}
|
||||
uc.upgradeContainerService, uc.upgradeAPIVersion, err = upgradeapiloader.LoadUpgradeContainerServiceFromFile(uc.upgradeModelFile)
|
||||
// validate upgrade and set the Goal State
|
||||
contents, err := ioutil.ReadFile(uc.upgradeModelFile)
|
||||
if err != nil {
|
||||
log.Fatalf("error parsing the upgrade api model: %s", err.Error())
|
||||
log.Fatalf("error reading file %s: %s", uc.upgradeModelFile, err.Error())
|
||||
}
|
||||
if err = apiloader.UpdateContainerServiceForUpgrade(contents, vlabs.APIVersion, uc.containerService, true); err != nil {
|
||||
log.Fatalf("error loading ContainerService: %s", err.Error())
|
||||
}
|
||||
|
||||
uc.client, err = uc.authArgs.getClient()
|
||||
|
@ -135,7 +132,7 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {
|
|||
// user could have specified a name suffix instead of using the default
|
||||
// value generated by ACS Engine
|
||||
templatePath := path.Join(uc.deploymentDirectory, "azuredeploy.json")
|
||||
contents, _ := ioutil.ReadFile(templatePath)
|
||||
contents, _ = ioutil.ReadFile(templatePath)
|
||||
|
||||
var template interface{}
|
||||
json.Unmarshal(contents, &template)
|
||||
|
@ -159,7 +156,7 @@ func (uc *upgradeCmd) run(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
if err := upgradeCluster.UpgradeCluster(uc.authArgs.SubscriptionID, uc.resourceGroupName,
|
||||
uc.containerService, uc.upgradeContainerService, uc.nameSuffix); err != nil {
|
||||
uc.containerService, uc.nameSuffix); err != nil {
|
||||
log.Fatalf("Error upgrading cluster: %s \n", err.Error())
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,15 @@
|
|||
## Overview
|
||||
|
||||
This document describes how to upgrade kubernetes version on a running cluster.
|
||||
The upgrade is an **experimental** feature, and currently under development.
|
||||
|
||||
Supported scenario: upgrade from v1.5 to v1.6
|
||||
Supported scenarios:
|
||||
- upgrade from v1.5 to v1.6
|
||||
- upgrade from v1.6 to v1.7
|
||||
|
||||
The cluster definition file examples demonstrate initial cluster configurations:
|
||||
- **kubernetes1.5.json** - Kubernetes cluster v1.5 with Linux agent pool
|
||||
- **kubernetes1.5-win.json** - Kubernetes cluster v1.5 with Windows agent pool
|
||||
- **kubernetes1.5-hybrid.json** - Kubernetes cluster v1.5 with Linux and Windows agent pools
|
||||
- **kubernetes1.6.json** - Kubernetes cluster v1.6 with Linux agent pool
|
||||
|
||||
The ***.env** files are used to set desired kubernetes version and instruct test framework to invoke post-deploy instructions implemented in **k8s-upgrade.sh** script.
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
set -e
|
||||
|
||||
export ACSENGINE_EXPERIMENTAL_FEATURES=1
|
||||
|
||||
# some tests set EXPECTED_ORCHESTRATOR_RELEASE in .env files
|
||||
ENV_FILE="${CLUSTER_DEFINITION}.env"
|
||||
if [ -e "${ENV_FILE}" ]; then
|
||||
|
@ -17,11 +15,8 @@ K8S_UPGRADE_CONF="$OUTPUT/k8sUpgrade.json"
|
|||
|
||||
cat > $K8S_UPGRADE_CONF <<END
|
||||
{
|
||||
"apiVersion": "vlabs",
|
||||
"orchestratorProfile": {
|
||||
"orchestratorType": "Kubernetes",
|
||||
"orchestratorRelease": "${EXPECTED_ORCHESTRATOR_RELEASE}"
|
||||
}
|
||||
"orchestratorType": "Kubernetes",
|
||||
"orchestratorRelease": "${EXPECTED_ORCHESTRATOR_RELEASE}"
|
||||
}
|
||||
END
|
||||
|
||||
|
|
|
@ -89,17 +89,6 @@ const (
|
|||
DCOSPublicAgent DCOSNodeType = "DCOSPublicAgent"
|
||||
)
|
||||
|
||||
const (
|
||||
// SwarmVersion is the Swarm orchestrator version
|
||||
SwarmVersion = "swarm:1.1.0"
|
||||
// SwarmDockerComposeVersion is the Docker Compose version
|
||||
SwarmDockerComposeVersion = "1.6.2"
|
||||
// DockerCEVersion is the DockerCE orchestrator version
|
||||
DockerCEVersion = "17.03.*"
|
||||
// DockerCEDockerComposeVersion is the Docker Compose version
|
||||
DockerCEDockerComposeVersion = "1.14.0"
|
||||
)
|
||||
|
||||
// KubeConfigs represents Docker images used for Kubernetes components based on Kubernetes releases (major.minor)
|
||||
// For instance, Kubernetes release "1.7" would contain the version "1.7.2"
|
||||
var KubeConfigs = map[string]map[string]string{
|
||||
|
|
|
@ -784,10 +784,10 @@ func (t *TemplateGenerator) getTemplateFuncMap(cs *api.ContainerService) templat
|
|||
return GetMasterAgentAllowedSizes()
|
||||
},
|
||||
"getSwarmVersions": func() string {
|
||||
return getSwarmVersions(SwarmVersion, SwarmDockerComposeVersion)
|
||||
return getSwarmVersions(api.SwarmVersion, api.SwarmDockerComposeVersion)
|
||||
},
|
||||
"GetSwarmModeVersions": func() string {
|
||||
return getSwarmVersions(DockerCEVersion, DockerCEDockerComposeVersion)
|
||||
return getSwarmVersions(api.DockerCEVersion, api.DockerCEDockerComposeVersion)
|
||||
},
|
||||
"GetSizeMap": func() string {
|
||||
if t.ClassicMode {
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
package acsengine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
"github.com/Azure/acs-engine/pkg/api/common"
|
||||
)
|
||||
|
||||
type orchestratorsFunc func(*api.OrchestratorEdition) ([]*api.OrchestratorVersionProfile, error)
|
||||
|
||||
var funcmap map[string]orchestratorsFunc
|
||||
|
||||
type versionNumber struct {
|
||||
major, minor, patch int64
|
||||
}
|
||||
|
||||
func (v *versionNumber) parse(ver string) (err error) {
|
||||
arr := strings.Split(ver, ".")
|
||||
if len(arr) != 3 {
|
||||
return fmt.Errorf("Illegal version format '%s'", ver)
|
||||
}
|
||||
if v.major, err = strconv.ParseInt(arr[0], 10, 32); err != nil {
|
||||
return
|
||||
}
|
||||
if v.minor, err = strconv.ParseInt(arr[1], 10, 32); err != nil {
|
||||
return
|
||||
}
|
||||
if v.patch, err = strconv.ParseInt(arr[2], 10, 32); err != nil {
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *versionNumber) greaterThan(o *versionNumber) bool {
|
||||
// check major
|
||||
if v.major != o.major {
|
||||
return v.major > o.major
|
||||
}
|
||||
// same major; check minor
|
||||
if v.minor != o.minor {
|
||||
return v.minor > o.minor
|
||||
}
|
||||
// same minor; check patch
|
||||
return v.patch > o.patch
|
||||
}
|
||||
|
||||
func init() {
|
||||
funcmap = map[string]orchestratorsFunc{
|
||||
api.Kubernetes: kubernetesInfo,
|
||||
api.DCOS: dcosInfo,
|
||||
api.Swarm: swarmInfo,
|
||||
api.SwarmMode: dockerceInfo,
|
||||
}
|
||||
}
|
||||
|
||||
func validate(orchestrator, release string) (string, error) {
|
||||
switch {
|
||||
case strings.EqualFold(orchestrator, api.Kubernetes):
|
||||
return api.Kubernetes, nil
|
||||
case strings.EqualFold(orchestrator, api.DCOS):
|
||||
return api.DCOS, nil
|
||||
case strings.EqualFold(orchestrator, api.Swarm):
|
||||
return api.Swarm, nil
|
||||
case strings.EqualFold(orchestrator, api.SwarmMode):
|
||||
return api.SwarmMode, nil
|
||||
case len(orchestrator) == 0:
|
||||
if len(release) > 0 {
|
||||
return "", fmt.Errorf("Must specify orchestrator for release '%s'", release)
|
||||
}
|
||||
default:
|
||||
return "", fmt.Errorf("Unsupported orchestrator '%s'", orchestrator)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// GetOrchestratorVersionProfileList returns OrchestratorVersionProfileList object per (optionally) specified orchestrator and release
|
||||
func GetOrchestratorVersionProfileList(orchestrator, release string) (*api.OrchestratorVersionProfileList, error) {
|
||||
var err error
|
||||
if orchestrator, err = validate(orchestrator, release); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orch := &api.OrchestratorVersionProfileList{}
|
||||
|
||||
if len(orchestrator) == 0 {
|
||||
// return all orchestrators
|
||||
orch.Orchestrators = []*api.OrchestratorVersionProfile{}
|
||||
for _, f := range funcmap {
|
||||
arr, err := f(&api.OrchestratorEdition{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orch.Orchestrators = append(orch.Orchestrators, arr...)
|
||||
}
|
||||
return orch, nil
|
||||
}
|
||||
if orch.Orchestrators, err = funcmap[orchestrator](&api.OrchestratorEdition{OrchestratorRelease: release}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orch, nil
|
||||
}
|
||||
|
||||
// GetOrchestratorVersionProfile returns orchestrator info for upgradable container service
|
||||
func GetOrchestratorVersionProfile(cs *api.ContainerService) (*api.OrchestratorVersionProfile, error) {
|
||||
if cs == nil || cs.Properties == nil || cs.Properties.OrchestratorProfile == nil {
|
||||
return nil, fmt.Errorf("Incomplete ContainerService")
|
||||
}
|
||||
if len(cs.Properties.OrchestratorProfile.OrchestratorRelease) == 0 {
|
||||
return nil, fmt.Errorf("Missing Orchestrator Release")
|
||||
}
|
||||
if cs.Properties.OrchestratorProfile.OrchestratorType != api.Kubernetes {
|
||||
return nil, fmt.Errorf("Upgrade operation is not supported for '%s'", cs.Properties.OrchestratorProfile.OrchestratorType)
|
||||
}
|
||||
arr, err := kubernetesInfo(&api.OrchestratorEdition{
|
||||
OrchestratorRelease: cs.Properties.OrchestratorProfile.OrchestratorRelease,
|
||||
OrchestratorVersion: cs.Properties.OrchestratorProfile.OrchestratorVersion})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// has to be exactly one element per specified orchestrator/release
|
||||
if len(arr) != 1 {
|
||||
return nil, fmt.Errorf("Umbiguous Orchestrator Releases")
|
||||
}
|
||||
return arr[0], nil
|
||||
}
|
||||
|
||||
func kubernetesInfo(csOrch *api.OrchestratorEdition) ([]*api.OrchestratorVersionProfile, error) {
|
||||
orchs := []*api.OrchestratorVersionProfile{}
|
||||
if len(csOrch.OrchestratorRelease) == 0 {
|
||||
// get info for all supported versions
|
||||
for rel, ver := range common.KubeReleaseToVersion {
|
||||
upgrades, err := kubernetesUpgrades(&api.OrchestratorEdition{OrchestratorRelease: rel, OrchestratorVersion: ver})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orchs = append(orchs,
|
||||
&api.OrchestratorVersionProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorEdition: api.OrchestratorEdition{
|
||||
OrchestratorRelease: rel,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: rel == common.KubernetesDefaultRelease,
|
||||
Upgradables: upgrades,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// get info for the specified release
|
||||
ver, ok := common.KubeReleaseToVersion[csOrch.OrchestratorRelease]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Kubernetes release %s is not supported", csOrch.OrchestratorRelease)
|
||||
}
|
||||
// set default version if empty
|
||||
if len(csOrch.OrchestratorVersion) == 0 {
|
||||
csOrch.OrchestratorVersion = ver
|
||||
}
|
||||
upgrades, err := kubernetesUpgrades(csOrch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orchs = append(orchs,
|
||||
&api.OrchestratorVersionProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorEdition: api.OrchestratorEdition{
|
||||
OrchestratorRelease: csOrch.OrchestratorRelease,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: csOrch.OrchestratorRelease == common.KubernetesDefaultRelease,
|
||||
Upgradables: upgrades,
|
||||
})
|
||||
}
|
||||
return orchs, nil
|
||||
}
|
||||
|
||||
func kubernetesUpgrades(csOrch *api.OrchestratorEdition) ([]*api.OrchestratorEdition, error) {
|
||||
ret := []*api.OrchestratorEdition{}
|
||||
var csVer versionNumber
|
||||
var err error
|
||||
|
||||
if err = csVer.parse(csOrch.OrchestratorVersion); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
switch csOrch.OrchestratorRelease {
|
||||
case common.KubernetesRelease1Dot5:
|
||||
// add next release
|
||||
ret = append(ret, &api.OrchestratorEdition{
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot6,
|
||||
OrchestratorVersion: common.KubeReleaseToVersion[common.KubernetesRelease1Dot6],
|
||||
})
|
||||
case common.KubernetesRelease1Dot6:
|
||||
// check for patch upgrade
|
||||
if ret, err = addPatchUpgrade(ret, &csVer, csOrch.OrchestratorRelease); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
// add next release
|
||||
ret = append(ret, &api.OrchestratorEdition{
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot7,
|
||||
OrchestratorVersion: common.KubeReleaseToVersion[common.KubernetesRelease1Dot7],
|
||||
})
|
||||
case common.KubernetesRelease1Dot7:
|
||||
// check for patch upgrade
|
||||
if ret, err = addPatchUpgrade(ret, &csVer, csOrch.OrchestratorRelease); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func addPatchUpgrade(upgrades []*api.OrchestratorEdition, csVer *versionNumber, release string) ([]*api.OrchestratorEdition, error) {
|
||||
var pVer versionNumber
|
||||
patchVersion := common.KubeReleaseToVersion[release]
|
||||
if err := pVer.parse(patchVersion); err != nil {
|
||||
return upgrades, err
|
||||
}
|
||||
if pVer.greaterThan(csVer) {
|
||||
upgrades = append(upgrades, &api.OrchestratorEdition{OrchestratorRelease: release, OrchestratorVersion: patchVersion})
|
||||
}
|
||||
return upgrades, nil
|
||||
}
|
||||
|
||||
func dcosInfo(csOrch *api.OrchestratorEdition) ([]*api.OrchestratorVersionProfile, error) {
|
||||
orchs := []*api.OrchestratorVersionProfile{}
|
||||
if len(csOrch.OrchestratorRelease) == 0 {
|
||||
// get info for all supported versions
|
||||
for rel, ver := range common.DCOSReleaseToVersion {
|
||||
orchs = append(orchs,
|
||||
&api.OrchestratorVersionProfile{
|
||||
OrchestratorType: api.DCOS,
|
||||
OrchestratorEdition: api.OrchestratorEdition{
|
||||
OrchestratorRelease: rel,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: rel == common.DCOSDefaultRelease,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// get info for the specified release
|
||||
ver, ok := common.DCOSReleaseToVersion[csOrch.OrchestratorRelease]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("DCOS release %s is not supported", csOrch.OrchestratorRelease)
|
||||
}
|
||||
orchs = append(orchs,
|
||||
&api.OrchestratorVersionProfile{
|
||||
OrchestratorType: api.DCOS,
|
||||
OrchestratorEdition: api.OrchestratorEdition{
|
||||
OrchestratorRelease: csOrch.OrchestratorRelease,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: csOrch.OrchestratorRelease == common.DCOSDefaultRelease,
|
||||
})
|
||||
}
|
||||
return orchs, nil
|
||||
}
|
||||
|
||||
func swarmInfo(csOrch *api.OrchestratorEdition) ([]*api.OrchestratorVersionProfile, error) {
|
||||
return []*api.OrchestratorVersionProfile{
|
||||
{
|
||||
OrchestratorType: api.Swarm,
|
||||
OrchestratorEdition: api.OrchestratorEdition{
|
||||
OrchestratorVersion: SwarmVersion,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func dockerceInfo(csOrch *api.OrchestratorEdition) ([]*api.OrchestratorVersionProfile, error) {
|
||||
return []*api.OrchestratorVersionProfile{
|
||||
{
|
||||
OrchestratorType: api.SwarmMode,
|
||||
OrchestratorEdition: api.OrchestratorEdition{
|
||||
OrchestratorVersion: DockerCEVersion,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
package acsengine
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
"github.com/Azure/acs-engine/pkg/api/common"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestInvalidVersion(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
|
||||
invalid := []string{
|
||||
"invalid number",
|
||||
"invalid.number",
|
||||
"a4.b7.c3",
|
||||
"31.29.",
|
||||
".17.02",
|
||||
"43.156.89.",
|
||||
"1.2.a"}
|
||||
var ver versionNumber
|
||||
|
||||
for _, v := range invalid {
|
||||
e := ver.parse(v)
|
||||
Expect(e).NotTo(BeNil())
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionCompare(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
|
||||
type record struct {
|
||||
v1, v2 string
|
||||
isGreater bool
|
||||
}
|
||||
records := []record{
|
||||
{"37.48.59", "37.48.59", false},
|
||||
{"17.4.5", "3.1.1", true},
|
||||
{"9.6.5", "9.45.5", false},
|
||||
{"2.3.8", "2.3.24", false}}
|
||||
var ver1, ver2 versionNumber
|
||||
|
||||
for _, r := range records {
|
||||
e := ver1.parse(r.v1)
|
||||
Expect(e).To(BeNil())
|
||||
e = ver2.parse(r.v2)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(r.isGreater).To(Equal(ver1.greaterThan(&ver2)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrchestratorUpgradeInfo(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
|
||||
// 1.5.3 is upgradable to 1.6
|
||||
cs := &api.ContainerService{
|
||||
Properties: &api.Properties{
|
||||
OrchestratorProfile: &api.OrchestratorProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot5,
|
||||
OrchestratorVersion: "1.5.3",
|
||||
},
|
||||
},
|
||||
}
|
||||
orch, e := GetOrchestratorVersionProfile(cs)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgradables)).To(Equal(1))
|
||||
Expect(orch.Upgradables[0].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot6))
|
||||
Expect(orch.Upgradables[0].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot6]))
|
||||
|
||||
// 1.6.0 is upgradable to 1.6 and 1.7
|
||||
cs = &api.ContainerService{
|
||||
Properties: &api.Properties{
|
||||
OrchestratorProfile: &api.OrchestratorProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot6,
|
||||
OrchestratorVersion: "1.6.0",
|
||||
},
|
||||
},
|
||||
}
|
||||
orch, e = GetOrchestratorVersionProfile(cs)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgradables)).To(Equal(2))
|
||||
Expect(orch.Upgradables[0].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot6))
|
||||
Expect(orch.Upgradables[0].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot6]))
|
||||
Expect(orch.Upgradables[1].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot7))
|
||||
Expect(orch.Upgradables[1].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot7]))
|
||||
|
||||
// 1.7.0 is upgradable to 1.7
|
||||
cs = &api.ContainerService{
|
||||
Properties: &api.Properties{
|
||||
OrchestratorProfile: &api.OrchestratorProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot7,
|
||||
OrchestratorVersion: "1.7.0",
|
||||
},
|
||||
},
|
||||
}
|
||||
orch, e = GetOrchestratorVersionProfile(cs)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgradables)).To(Equal(1))
|
||||
Expect(orch.Upgradables[0].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot7))
|
||||
Expect(orch.Upgradables[0].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot7]))
|
||||
|
||||
// 1.7 is not upgradable
|
||||
cs = &api.ContainerService{
|
||||
Properties: &api.Properties{
|
||||
OrchestratorProfile: &api.OrchestratorProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot7,
|
||||
OrchestratorVersion: common.KubeReleaseToVersion[common.KubernetesRelease1Dot7],
|
||||
},
|
||||
},
|
||||
}
|
||||
orch, e = GetOrchestratorVersionProfile(cs)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgradables)).To(Equal(0))
|
||||
}
|
|
@ -4,6 +4,9 @@ import (
|
|||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api/common"
|
||||
"github.com/Azure/acs-engine/pkg/api/v20170930"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api/agentPoolOnlyApi/v20170831"
|
||||
apvlabs "github.com/Azure/acs-engine/pkg/api/agentPoolOnlyApi/vlabs"
|
||||
"github.com/Azure/acs-engine/pkg/api/v20160330"
|
||||
|
@ -171,6 +174,64 @@ func (a *Apiloader) LoadContainerServiceForAgentPoolOnlyCluster(contents []byte,
|
|||
}
|
||||
}
|
||||
|
||||
// UpdateContainerServiceForUpgrade pre-validates upgrade operation and updates container service
|
||||
func (a *Apiloader) UpdateContainerServiceForUpgrade(
|
||||
contents []byte,
|
||||
version string,
|
||||
cs *ContainerService,
|
||||
allowCurrentVersionUpgrade bool) error {
|
||||
unverOrch := &OrchestratorProfile{}
|
||||
|
||||
switch version {
|
||||
case v20170930.APIVersion:
|
||||
up := &v20170930.OrchestratorProfile{}
|
||||
if e := json.Unmarshal(contents, up); e != nil {
|
||||
return a.Translator.Errorf(e.Error())
|
||||
}
|
||||
if e := up.ValidateForUpgrade(); e != nil {
|
||||
return a.Translator.Errorf(e.Error())
|
||||
}
|
||||
convertV20170930OrchestratorProfile(up, unverOrch)
|
||||
|
||||
case vlabs.APIVersion:
|
||||
up := &vlabs.OrchestratorProfile{}
|
||||
if e := json.Unmarshal(contents, up); e != nil {
|
||||
return a.Translator.Errorf(e.Error())
|
||||
}
|
||||
if e := up.ValidateForUpgrade(); e != nil {
|
||||
return a.Translator.Errorf(e.Error())
|
||||
}
|
||||
convertVLabsOrchestratorProfile(up, unverOrch)
|
||||
|
||||
default:
|
||||
return a.Translator.Errorf("unrecognized APIVersion in UpdateContainerServiceForUpgrade '%s'", version)
|
||||
}
|
||||
|
||||
// get available upgrades for container service
|
||||
orchestratorInfo, e := GetOrchestratorVersionProfile(cs.Properties.OrchestratorProfile)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
// add current version if upgrade has failed
|
||||
if allowCurrentVersionUpgrade {
|
||||
release := cs.Properties.OrchestratorProfile.OrchestratorRelease
|
||||
orchestratorInfo.Upgrades = append(orchestratorInfo.Upgrades, &OrchestratorProfile{
|
||||
OrchestratorRelease: release,
|
||||
OrchestratorVersion: common.KubeReleaseToVersion[release]})
|
||||
}
|
||||
// validate desired upgrade version and set goal state
|
||||
for _, up := range orchestratorInfo.Upgrades {
|
||||
if up.OrchestratorRelease == unverOrch.OrchestratorRelease {
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = up.OrchestratorRelease
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = up.OrchestratorVersion
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return a.Translator.Errorf("Kubernetes %s cannot be upgraded to %s",
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease, unverOrch.OrchestratorRelease)
|
||||
}
|
||||
|
||||
// SerializeContainerService takes an unversioned container service and returns the bytes
|
||||
func (a *Apiloader) SerializeContainerService(containerService *ContainerService, version string) ([]byte, error) {
|
||||
if containerService.Properties != nil && containerService.Properties.HostedMasterProfile != nil {
|
||||
|
|
|
@ -20,6 +20,17 @@ const (
|
|||
Linux OSType = "Linux"
|
||||
)
|
||||
|
||||
const (
|
||||
// SwarmVersion is the Swarm orchestrator version
|
||||
SwarmVersion = "swarm:1.1.0"
|
||||
// SwarmDockerComposeVersion is the Docker Compose version
|
||||
SwarmDockerComposeVersion = "1.6.2"
|
||||
// DockerCEVersion is the DockerCE orchestrator version
|
||||
DockerCEVersion = "17.03.*"
|
||||
// DockerCEDockerComposeVersion is the Docker Compose version
|
||||
DockerCEDockerComposeVersion = "1.14.0"
|
||||
)
|
||||
|
||||
// validation values
|
||||
const (
|
||||
// MinAgentCount are the minimum number of agents per agent pool
|
||||
|
|
|
@ -136,10 +136,10 @@ func ConvertOrchestratorVersionProfileToV20170930(api *OrchestratorVersionProfil
|
|||
vProfile.OrchestratorVersion = api.OrchestratorVersion
|
||||
vProfile.OrchestratorRelease = api.OrchestratorRelease
|
||||
vProfile.Default = api.Default
|
||||
if api.Upgradables != nil {
|
||||
vProfile.Upgradables = make([]*v20170930.OrchestratorEdition, len(api.Upgradables))
|
||||
for i, h := range api.Upgradables {
|
||||
vProfile.Upgradables[i] = &v20170930.OrchestratorEdition{
|
||||
if api.Upgrades != nil {
|
||||
vProfile.Upgrades = make([]*v20170930.OrchestratorProfile, len(api.Upgrades))
|
||||
for i, h := range api.Upgrades {
|
||||
vProfile.Upgrades[i] = &v20170930.OrchestratorProfile{
|
||||
OrchestratorRelease: h.OrchestratorRelease,
|
||||
OrchestratorVersion: h.OrchestratorVersion,
|
||||
}
|
||||
|
@ -164,10 +164,10 @@ func ConvertOrchestratorVersionProfileToVLabs(api *OrchestratorVersionProfile) *
|
|||
vlabsProfile.OrchestratorVersion = api.OrchestratorVersion
|
||||
vlabsProfile.OrchestratorRelease = api.OrchestratorRelease
|
||||
vlabsProfile.Default = api.Default
|
||||
if api.Upgradables != nil {
|
||||
vlabsProfile.Upgradables = make([]*vlabs.OrchestratorEdition, len(api.Upgradables))
|
||||
for i, h := range api.Upgradables {
|
||||
vlabsProfile.Upgradables[i] = &vlabs.OrchestratorEdition{
|
||||
if api.Upgrades != nil {
|
||||
vlabsProfile.Upgrades = make([]*vlabs.OrchestratorProfile, len(api.Upgrades))
|
||||
for i, h := range api.Upgrades {
|
||||
vlabsProfile.Upgrades[i] = &vlabs.OrchestratorProfile{
|
||||
OrchestratorRelease: h.OrchestratorRelease,
|
||||
OrchestratorVersion: h.OrchestratorVersion,
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package api
|
||||
|
||||
import "github.com/Azure/acs-engine/pkg/api/vlabs"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// The converter exposes functions to convert the top level
|
||||
// ContainerService resource
|
||||
//
|
||||
// All other functions are internal helper functions used
|
||||
// for converting.
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// ConvertUpgradeContainerServiceToVLabs converts an unversioned ContainerService to a vlabs ContainerService
|
||||
func ConvertUpgradeContainerServiceToVLabs(api *UpgradeContainerService) *vlabs.UpgradeContainerService {
|
||||
vlabsUCS := &vlabs.UpgradeContainerService{}
|
||||
vlabsUCS.OrchestratorProfile = &vlabs.OrchestratorProfile{}
|
||||
convertUpgradeOrchestratorProfileToVLabs(api.OrchestratorProfile, vlabsUCS.OrchestratorProfile)
|
||||
return vlabsUCS
|
||||
}
|
||||
|
||||
func convertUpgradeOrchestratorProfileToVLabs(api *OrchestratorProfile, o *vlabs.OrchestratorProfile) {
|
||||
o.OrchestratorType = api.OrchestratorType
|
||||
|
||||
if api.OrchestratorVersion != "" {
|
||||
o.OrchestratorVersion = api.OrchestratorVersion
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/Azure/acs-engine/pkg/api/v20160930"
|
||||
"github.com/Azure/acs-engine/pkg/api/v20170131"
|
||||
"github.com/Azure/acs-engine/pkg/api/v20170701"
|
||||
"github.com/Azure/acs-engine/pkg/api/v20170930"
|
||||
"github.com/Azure/acs-engine/pkg/api/vlabs"
|
||||
)
|
||||
|
||||
|
@ -528,6 +529,21 @@ func convertV20170131OrchestratorProfile(v20170131 *v20170131.OrchestratorProfil
|
|||
}
|
||||
}
|
||||
|
||||
func convertV20170930OrchestratorProfile(v *v20170930.OrchestratorProfile, api *OrchestratorProfile) {
|
||||
switch v.OrchestratorType {
|
||||
case v20170930.Kubernetes:
|
||||
api.OrchestratorType = Kubernetes
|
||||
case v20170930.DCOS:
|
||||
api.OrchestratorType = DCOS
|
||||
case v20170930.Swarm:
|
||||
api.OrchestratorType = Swarm
|
||||
case v20170930.DockerCE:
|
||||
api.OrchestratorType = SwarmMode
|
||||
}
|
||||
api.OrchestratorRelease = v.OrchestratorRelease
|
||||
api.OrchestratorVersion = v.OrchestratorVersion
|
||||
}
|
||||
|
||||
func convertV20170701OrchestratorProfile(v20170701cs *v20170701.OrchestratorProfile, api *OrchestratorProfile) {
|
||||
if v20170701cs.OrchestratorType == v20170701.DockerCE {
|
||||
api.OrchestratorType = SwarmMode
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package api
|
||||
|
||||
import "github.com/Azure/acs-engine/pkg/api/vlabs"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// The converter exposes functions to convert the top level
|
||||
// UpgradeContainerService API model
|
||||
//
|
||||
// All other functions are internal helper functions used
|
||||
// for converting.
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// ConvertVLabsUpgradeContainerService converts a vlabs UpgradeContainerService to an unversioned UpgradeContainerService
|
||||
func ConvertVLabsUpgradeContainerService(vlabs *vlabs.UpgradeContainerService) *UpgradeContainerService {
|
||||
ucs := &UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &OrchestratorProfile{}
|
||||
convertVLabsOrchestratorProfile(vlabs.OrchestratorProfile, ucs.OrchestratorProfile)
|
||||
return ucs
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api/common"
|
||||
"github.com/Masterminds/semver"
|
||||
)
|
||||
|
||||
type orchestratorsFunc func(*OrchestratorProfile) ([]*OrchestratorVersionProfile, error)
|
||||
|
||||
var funcmap map[string]orchestratorsFunc
|
||||
|
||||
func init() {
|
||||
funcmap = map[string]orchestratorsFunc{
|
||||
Kubernetes: kubernetesInfo,
|
||||
DCOS: dcosInfo,
|
||||
Swarm: swarmInfo,
|
||||
SwarmMode: dockerceInfo,
|
||||
}
|
||||
}
|
||||
|
||||
func validate(orchestrator, release string) (string, error) {
|
||||
switch {
|
||||
case strings.EqualFold(orchestrator, Kubernetes):
|
||||
return Kubernetes, nil
|
||||
case strings.EqualFold(orchestrator, DCOS):
|
||||
return DCOS, nil
|
||||
case strings.EqualFold(orchestrator, Swarm):
|
||||
return Swarm, nil
|
||||
case strings.EqualFold(orchestrator, SwarmMode):
|
||||
return SwarmMode, nil
|
||||
case len(orchestrator) == 0:
|
||||
if len(release) > 0 {
|
||||
return "", fmt.Errorf("Must specify orchestrator for release '%s'", release)
|
||||
}
|
||||
default:
|
||||
return "", fmt.Errorf("Unsupported orchestrator '%s'", orchestrator)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// GetOrchestratorVersionProfileList returns OrchestratorVersionProfileList object per (optionally) specified orchestrator and release
|
||||
func GetOrchestratorVersionProfileList(orchestrator, release string) (*OrchestratorVersionProfileList, error) {
|
||||
var err error
|
||||
if orchestrator, err = validate(orchestrator, release); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orch := &OrchestratorVersionProfileList{}
|
||||
|
||||
if len(orchestrator) == 0 {
|
||||
// return all orchestrators
|
||||
orch.Orchestrators = []*OrchestratorVersionProfile{}
|
||||
for _, f := range funcmap {
|
||||
arr, err := f(&OrchestratorProfile{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orch.Orchestrators = append(orch.Orchestrators, arr...)
|
||||
}
|
||||
return orch, nil
|
||||
}
|
||||
if orch.Orchestrators, err = funcmap[orchestrator](&OrchestratorProfile{OrchestratorRelease: release}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orch, nil
|
||||
}
|
||||
|
||||
// GetOrchestratorVersionProfile returns orchestrator info for upgradable container service
|
||||
func GetOrchestratorVersionProfile(orch *OrchestratorProfile) (*OrchestratorVersionProfile, error) {
|
||||
if len(orch.OrchestratorRelease) == 0 {
|
||||
return nil, fmt.Errorf("Missing Orchestrator Release")
|
||||
}
|
||||
if orch.OrchestratorType != Kubernetes {
|
||||
return nil, fmt.Errorf("Upgrade operation is not supported for '%s'", orch.OrchestratorType)
|
||||
}
|
||||
arr, err := kubernetesInfo(orch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// has to be exactly one element per specified orchestrator/release
|
||||
if len(arr) != 1 {
|
||||
return nil, fmt.Errorf("Umbiguous Orchestrator Releases")
|
||||
}
|
||||
return arr[0], nil
|
||||
}
|
||||
|
||||
func kubernetesInfo(csOrch *OrchestratorProfile) ([]*OrchestratorVersionProfile, error) {
|
||||
orchs := []*OrchestratorVersionProfile{}
|
||||
if len(csOrch.OrchestratorRelease) == 0 {
|
||||
// get info for all supported versions
|
||||
for rel, ver := range common.KubeReleaseToVersion {
|
||||
upgrades, err := kubernetesUpgrades(&OrchestratorProfile{OrchestratorRelease: rel, OrchestratorVersion: ver})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orchs = append(orchs,
|
||||
&OrchestratorVersionProfile{
|
||||
OrchestratorProfile: OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: rel,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: rel == common.KubernetesDefaultRelease,
|
||||
Upgrades: upgrades,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// get info for the specified release
|
||||
ver, ok := common.KubeReleaseToVersion[csOrch.OrchestratorRelease]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Kubernetes release %s is not supported", csOrch.OrchestratorRelease)
|
||||
}
|
||||
// set default version if empty
|
||||
if len(csOrch.OrchestratorVersion) == 0 {
|
||||
csOrch.OrchestratorVersion = ver
|
||||
}
|
||||
upgrades, err := kubernetesUpgrades(csOrch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orchs = append(orchs,
|
||||
&OrchestratorVersionProfile{
|
||||
OrchestratorProfile: OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: csOrch.OrchestratorRelease,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: csOrch.OrchestratorRelease == common.KubernetesDefaultRelease,
|
||||
Upgrades: upgrades,
|
||||
})
|
||||
}
|
||||
return orchs, nil
|
||||
}
|
||||
|
||||
func kubernetesUpgrades(csOrch *OrchestratorProfile) ([]*OrchestratorProfile, error) {
|
||||
ret := []*OrchestratorProfile{}
|
||||
var err error
|
||||
|
||||
switch csOrch.OrchestratorRelease {
|
||||
case common.KubernetesRelease1Dot5:
|
||||
// add next release
|
||||
ret = append(ret, &OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot6,
|
||||
OrchestratorVersion: common.KubeReleaseToVersion[common.KubernetesRelease1Dot6],
|
||||
})
|
||||
case common.KubernetesRelease1Dot6:
|
||||
// check for patch upgrade
|
||||
if ret, err = addPatchUpgrade(ret, csOrch.OrchestratorRelease, csOrch.OrchestratorVersion); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
// add next release
|
||||
ret = append(ret, &OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot7,
|
||||
OrchestratorVersion: common.KubeReleaseToVersion[common.KubernetesRelease1Dot7],
|
||||
})
|
||||
case common.KubernetesRelease1Dot7:
|
||||
// check for patch upgrade
|
||||
if ret, err = addPatchUpgrade(ret, csOrch.OrchestratorRelease, csOrch.OrchestratorVersion); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func addPatchUpgrade(upgrades []*OrchestratorProfile, release, version string) ([]*OrchestratorProfile, error) {
|
||||
patchVersion, ok := common.KubeReleaseToVersion[release]
|
||||
if !ok {
|
||||
return upgrades, fmt.Errorf("Kubernetes release %s is not supported", release)
|
||||
}
|
||||
pVer, err := semver.NewVersion(patchVersion)
|
||||
if err != nil {
|
||||
return upgrades, err
|
||||
}
|
||||
constraint, err := semver.NewConstraint(">" + version)
|
||||
if err != nil {
|
||||
return upgrades, err
|
||||
}
|
||||
if constraint.Check(pVer) {
|
||||
upgrades = append(upgrades, &OrchestratorProfile{OrchestratorRelease: release, OrchestratorVersion: patchVersion})
|
||||
}
|
||||
return upgrades, nil
|
||||
}
|
||||
|
||||
func dcosInfo(csOrch *OrchestratorProfile) ([]*OrchestratorVersionProfile, error) {
|
||||
orchs := []*OrchestratorVersionProfile{}
|
||||
if len(csOrch.OrchestratorRelease) == 0 {
|
||||
// get info for all supported versions
|
||||
for rel, ver := range common.DCOSReleaseToVersion {
|
||||
orchs = append(orchs,
|
||||
&OrchestratorVersionProfile{
|
||||
OrchestratorProfile: OrchestratorProfile{
|
||||
OrchestratorType: DCOS,
|
||||
OrchestratorRelease: rel,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: rel == common.DCOSDefaultRelease,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// get info for the specified release
|
||||
ver, ok := common.DCOSReleaseToVersion[csOrch.OrchestratorRelease]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("DCOS release %s is not supported", csOrch.OrchestratorRelease)
|
||||
}
|
||||
orchs = append(orchs,
|
||||
&OrchestratorVersionProfile{
|
||||
OrchestratorProfile: OrchestratorProfile{
|
||||
OrchestratorType: DCOS,
|
||||
OrchestratorRelease: csOrch.OrchestratorRelease,
|
||||
OrchestratorVersion: ver,
|
||||
},
|
||||
Default: csOrch.OrchestratorRelease == common.DCOSDefaultRelease,
|
||||
})
|
||||
}
|
||||
return orchs, nil
|
||||
}
|
||||
|
||||
func swarmInfo(csOrch *OrchestratorProfile) ([]*OrchestratorVersionProfile, error) {
|
||||
return []*OrchestratorVersionProfile{
|
||||
{
|
||||
OrchestratorProfile: OrchestratorProfile{
|
||||
OrchestratorType: Swarm,
|
||||
OrchestratorVersion: SwarmVersion,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func dockerceInfo(csOrch *OrchestratorProfile) ([]*OrchestratorVersionProfile, error) {
|
||||
return []*OrchestratorVersionProfile{
|
||||
{
|
||||
OrchestratorProfile: OrchestratorProfile{
|
||||
OrchestratorType: SwarmMode,
|
||||
OrchestratorVersion: DockerCEVersion,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api/common"
|
||||
"github.com/Masterminds/semver"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestInvalidVersion(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
|
||||
invalid := []string{
|
||||
"invalid number",
|
||||
"invalid.number",
|
||||
"a4.b7.c3",
|
||||
"31.29.",
|
||||
".17.02",
|
||||
"43.156.89.",
|
||||
"1.2.a"}
|
||||
|
||||
for _, v := range invalid {
|
||||
_, e := semver.NewVersion(v)
|
||||
Expect(e).NotTo(BeNil())
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionCompare(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
|
||||
type record struct {
|
||||
v1, v2 string
|
||||
isGreater bool
|
||||
}
|
||||
records := []record{
|
||||
{"37.48.59", "37.48.59", false},
|
||||
{"17.4.5", "3.1.1", true},
|
||||
{"9.6.5", "9.45.5", false},
|
||||
{"2.3.8", "2.3.24", false}}
|
||||
|
||||
for _, r := range records {
|
||||
ver, e := semver.NewVersion(r.v1)
|
||||
Expect(e).To(BeNil())
|
||||
constraint, e := semver.NewConstraint(">" + r.v2)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(r.isGreater).To(Equal(constraint.Check(ver)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrchestratorUpgradeInfo(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
|
||||
// 1.5.3 is upgradable to 1.6
|
||||
csOrch := &OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot5,
|
||||
OrchestratorVersion: "1.5.3",
|
||||
}
|
||||
orch, e := GetOrchestratorVersionProfile(csOrch)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgrades)).To(Equal(1))
|
||||
Expect(orch.Upgrades[0].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot6))
|
||||
Expect(orch.Upgrades[0].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot6]))
|
||||
|
||||
// 1.6.0 is upgradable to 1.6 and 1.7
|
||||
csOrch = &OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot6,
|
||||
OrchestratorVersion: "1.6.0",
|
||||
}
|
||||
orch, e = GetOrchestratorVersionProfile(csOrch)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgrades)).To(Equal(2))
|
||||
Expect(orch.Upgrades[0].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot6))
|
||||
Expect(orch.Upgrades[0].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot6]))
|
||||
Expect(orch.Upgrades[1].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot7))
|
||||
Expect(orch.Upgrades[1].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot7]))
|
||||
|
||||
// 1.7.0 is upgradable to 1.7
|
||||
csOrch = &OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot7,
|
||||
OrchestratorVersion: "1.7.0",
|
||||
}
|
||||
orch, e = GetOrchestratorVersionProfile(csOrch)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgrades)).To(Equal(1))
|
||||
Expect(orch.Upgrades[0].OrchestratorRelease).To(Equal(common.KubernetesRelease1Dot7))
|
||||
Expect(orch.Upgrades[0].OrchestratorVersion).To(Equal(common.KubeReleaseToVersion[common.KubernetesRelease1Dot7]))
|
||||
|
||||
// 1.7 is not upgradable
|
||||
csOrch = &OrchestratorProfile{
|
||||
OrchestratorType: Kubernetes,
|
||||
OrchestratorRelease: common.KubernetesRelease1Dot7,
|
||||
OrchestratorVersion: common.KubeReleaseToVersion[common.KubernetesRelease1Dot7],
|
||||
}
|
||||
orch, e = GetOrchestratorVersionProfile(csOrch)
|
||||
Expect(e).To(BeNil())
|
||||
Expect(len(orch.Upgrades)).To(Equal(0))
|
||||
}
|
|
@ -1,17 +1,10 @@
|
|||
package api
|
||||
|
||||
// OrchestratorEdition contains version and release numbers
|
||||
type OrchestratorEdition struct {
|
||||
OrchestratorRelease string `json:"orchestratorRelease,omitempty"`
|
||||
OrchestratorVersion string `json:"orchestratorVersion"`
|
||||
}
|
||||
|
||||
// OrchestratorVersionProfile contains orchestrator version info
|
||||
type OrchestratorVersionProfile struct {
|
||||
OrchestratorType string `json:"orchestratorType"`
|
||||
OrchestratorEdition
|
||||
Default bool `json:"default,omitempty"`
|
||||
Upgradables []*OrchestratorEdition `json:"upgradables,omitempty"`
|
||||
OrchestratorProfile
|
||||
Default bool `json:"default,omitempty"`
|
||||
Upgrades []*OrchestratorProfile `json:"upgrades,omitempty"`
|
||||
}
|
||||
|
||||
// OrchestratorVersionProfileList contains list of version profiles for supported orchestrators
|
||||
|
|
|
@ -130,6 +130,8 @@ const (
|
|||
// Migrating means resource is being migrated from one subscription or
|
||||
// resource group to another
|
||||
Migrating ProvisioningState = "Migrating"
|
||||
// Upgrading means an existing ContainerService resource is being upgraded
|
||||
Upgrading ProvisioningState = "Upgrading"
|
||||
)
|
||||
|
||||
// OrchestratorProfile contains Orchestrator properties
|
||||
|
@ -253,7 +255,7 @@ type VMDiagnostics struct {
|
|||
StorageURL *neturl.URL `json:"storageUrl"`
|
||||
}
|
||||
|
||||
// JumpboxProfile dscribes properties of the jumpbox setup
|
||||
// JumpboxProfile describes properties of the jumpbox setup
|
||||
// in the ACS container cluster.
|
||||
type JumpboxProfile struct {
|
||||
OSType OSType `json:"osType"`
|
||||
|
@ -362,14 +364,6 @@ type V20170701ARMContainerService struct {
|
|||
*v20170701.ContainerService
|
||||
}
|
||||
|
||||
// VlabsUpgradeContainerService is the type we read and write from file
|
||||
// needed because the json that is sent to ARM and acs-engine
|
||||
// is different from the json that the ACS RP Api gets from ARM
|
||||
type VlabsUpgradeContainerService struct {
|
||||
TypeMeta
|
||||
*vlabs.UpgradeContainerService
|
||||
}
|
||||
|
||||
// V20170831ARMManagedContainerService is the type we read and write from file
|
||||
// needed because the json that is sent to ARM and acs-engine
|
||||
// is different from the json that the ACS RP Api gets from ARM
|
||||
|
@ -378,11 +372,6 @@ type V20170831ARMManagedContainerService struct {
|
|||
*v20170831.ManagedCluster
|
||||
}
|
||||
|
||||
// UpgradeContainerService API model
|
||||
type UpgradeContainerService struct {
|
||||
OrchestratorProfile *OrchestratorProfile `json:"orchestratorProfile,omitempty"`
|
||||
}
|
||||
|
||||
// HasWindows returns true if the cluster contains windows
|
||||
func (p *Properties) HasWindows() bool {
|
||||
for _, agentPoolProfile := range p.AgentPoolProfiles {
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api/vlabs"
|
||||
"github.com/Azure/acs-engine/pkg/i18n"
|
||||
)
|
||||
|
||||
// UpgradeApiloader represents the object that loads api model
|
||||
type UpgradeApiloader struct {
|
||||
Translator *i18n.Translator
|
||||
}
|
||||
|
||||
// LoadUpgradeContainerServiceFromFile loads an ACS Cluster API Model from a JSON file
|
||||
func (ua *UpgradeApiloader) LoadUpgradeContainerServiceFromFile(jsonFile string) (*UpgradeContainerService, string, error) {
|
||||
contents, e := ioutil.ReadFile(jsonFile)
|
||||
if e != nil {
|
||||
return nil, "", ua.Translator.Errorf("error reading file %s: %s", jsonFile, e.Error())
|
||||
}
|
||||
return ua.DeserializeUpgradeContainerService(contents)
|
||||
}
|
||||
|
||||
// DeserializeUpgradeContainerService loads an ACS Cluster API Model, validates it, and returns the unversioned representation
|
||||
func (ua *UpgradeApiloader) DeserializeUpgradeContainerService(contents []byte) (*UpgradeContainerService, string, error) {
|
||||
m := &TypeMeta{}
|
||||
if err := json.Unmarshal(contents, &m); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
version := m.APIVersion
|
||||
upgradecontainerservice, err := ua.LoadUpgradeContainerService(contents, version)
|
||||
|
||||
return upgradecontainerservice, version, err
|
||||
}
|
||||
|
||||
// LoadUpgradeContainerService loads an ACS Cluster API Model, validates it, and returns the unversioned representation
|
||||
func (ua *UpgradeApiloader) LoadUpgradeContainerService(contents []byte, version string) (*UpgradeContainerService, error) {
|
||||
switch version {
|
||||
case vlabs.APIVersion:
|
||||
upgradecontainerService := &vlabs.UpgradeContainerService{}
|
||||
if e := json.Unmarshal(contents, &upgradecontainerService); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
if e := upgradecontainerService.Validate(); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return ConvertVLabsUpgradeContainerService(upgradecontainerService), nil
|
||||
|
||||
default:
|
||||
return nil, ua.Translator.Errorf("unrecognized APIVersion '%s'", version)
|
||||
}
|
||||
}
|
||||
|
||||
// SerializeUpgradeContainerService takes an unversioned container service and returns the bytes
|
||||
func (ua *UpgradeApiloader) SerializeUpgradeContainerService(upgradeContainerService *UpgradeContainerService, version string) ([]byte, error) {
|
||||
switch version {
|
||||
case vlabs.APIVersion:
|
||||
vlabsUpgradeContainerService := ConvertUpgradeContainerServiceToVLabs(upgradeContainerService)
|
||||
armUpgradeContainerService := &VlabsUpgradeContainerService{}
|
||||
armUpgradeContainerService.UpgradeContainerService = vlabsUpgradeContainerService
|
||||
armUpgradeContainerService.APIVersion = version
|
||||
b, err := json.MarshalIndent(armUpgradeContainerService, "", " ")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
|
||||
default:
|
||||
return nil, ua.Translator.Errorf("invalid version %s for conversion back from unversioned object", version)
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
package v20170930
|
||||
|
||||
// OrchestratorEdition contains version and release numbers
|
||||
type OrchestratorEdition struct {
|
||||
OrchestratorRelease string `json:"orchestratorRelease,omitempty"`
|
||||
// OrchestratorProfile contains Orchestrator properties
|
||||
type OrchestratorProfile struct {
|
||||
OrchestratorType string `json:"orchestratorType"`
|
||||
OrchestratorRelease string `json:"orchestratorRelease"`
|
||||
OrchestratorVersion string `json:"orchestratorVersion"`
|
||||
}
|
||||
|
||||
// OrchestratorVersionProfile contains orchestrator version info
|
||||
type OrchestratorVersionProfile struct {
|
||||
OrchestratorType string `json:"orchestratorType"`
|
||||
OrchestratorEdition
|
||||
Default bool `json:"default,omitempty"`
|
||||
Upgradables []*OrchestratorEdition `json:"upgradables,omitempty"`
|
||||
OrchestratorProfile
|
||||
Default bool `json:"default,omitempty"`
|
||||
Upgrades []*OrchestratorProfile `json:"upgrades,omitempty"`
|
||||
}
|
||||
|
||||
// OrchestratorVersionProfileList contains list of version profiles for supported orchestrators
|
||||
|
|
|
@ -12,14 +12,8 @@ func (o *OrchestratorVersionProfile) Validate() error {
|
|||
switch {
|
||||
case strings.EqualFold(o.OrchestratorType, Kubernetes):
|
||||
o.OrchestratorType = Kubernetes
|
||||
if _, ok := common.KubeReleaseToVersion[o.OrchestratorRelease]; !ok {
|
||||
return fmt.Errorf("Unsupported Kubernetes release '%s'", o.OrchestratorRelease)
|
||||
}
|
||||
case strings.EqualFold(o.OrchestratorType, DCOS):
|
||||
o.OrchestratorType = DCOS
|
||||
if _, ok := common.DCOSReleaseToVersion[o.OrchestratorRelease]; !ok {
|
||||
return fmt.Errorf("Unsupported DCOS release '%s'", o.OrchestratorRelease)
|
||||
}
|
||||
case strings.EqualFold(o.OrchestratorType, Swarm):
|
||||
o.OrchestratorType = Swarm
|
||||
case strings.EqualFold(o.OrchestratorType, DockerCE):
|
||||
|
@ -29,3 +23,19 @@ func (o *OrchestratorVersionProfile) Validate() error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateForUpgrade validates upgrade input data
|
||||
func (o *OrchestratorProfile) ValidateForUpgrade() error {
|
||||
switch o.OrchestratorType {
|
||||
case DCOS, DockerCE, Swarm:
|
||||
return fmt.Errorf("Upgrade is not supported for orchestrator %s", o.OrchestratorType)
|
||||
case Kubernetes:
|
||||
switch o.OrchestratorRelease {
|
||||
case common.KubernetesRelease1Dot6:
|
||||
case common.KubernetesRelease1Dot7:
|
||||
default:
|
||||
return fmt.Errorf("Upgrade to Kubernetes %s is not supported", o.OrchestratorRelease)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
package vlabs
|
||||
|
||||
// OrchestratorEdition contains version and release numbers
|
||||
type OrchestratorEdition struct {
|
||||
OrchestratorRelease string `json:"orchestratorRelease,omitempty"`
|
||||
OrchestratorVersion string `json:"orchestratorVersion"`
|
||||
}
|
||||
|
||||
// OrchestratorVersionProfile contains orchestrator version info
|
||||
type OrchestratorVersionProfile struct {
|
||||
OrchestratorType string `json:"orchestratorType"`
|
||||
OrchestratorEdition
|
||||
Default bool `json:"default,omitempty"`
|
||||
Upgradables []*OrchestratorEdition `json:"upgradables,omitempty"`
|
||||
OrchestratorProfile
|
||||
Default bool `json:"default,omitempty"`
|
||||
Upgrades []*OrchestratorProfile `json:"upgrades,omitempty"`
|
||||
}
|
||||
|
||||
// OrchestratorVersionProfileList contains list of version profiles for supported orchestrators
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package vlabs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api/common"
|
||||
)
|
||||
|
||||
// UpgradeContainerService API model
|
||||
type UpgradeContainerService struct {
|
||||
OrchestratorProfile *OrchestratorProfile `json:"orchestratorProfile,omitempty"`
|
||||
}
|
||||
|
||||
// Validate implements APIObject
|
||||
func (ucs *UpgradeContainerService) Validate() error {
|
||||
switch ucs.OrchestratorProfile.OrchestratorType {
|
||||
case DCOS, SwarmMode, Swarm:
|
||||
return fmt.Errorf("Upgrade is not supported for orchestrator: %s", ucs.OrchestratorProfile.OrchestratorType)
|
||||
case Kubernetes:
|
||||
switch ucs.OrchestratorProfile.OrchestratorRelease {
|
||||
case common.KubernetesRelease1Dot6:
|
||||
case common.KubernetesRelease1Dot7:
|
||||
default:
|
||||
return fmt.Errorf("Upgrade is not supported to orchestrator release: %s", ucs.OrchestratorProfile.OrchestratorRelease)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -153,6 +153,22 @@ func (o *OrchestratorVersionProfile) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ValidateForUpgrade validates upgrade input data
|
||||
func (o *OrchestratorProfile) ValidateForUpgrade() error {
|
||||
switch o.OrchestratorType {
|
||||
case DCOS, SwarmMode, Swarm:
|
||||
return fmt.Errorf("Upgrade is not supported for orchestrator %s", o.OrchestratorType)
|
||||
case Kubernetes:
|
||||
switch o.OrchestratorRelease {
|
||||
case common.KubernetesRelease1Dot6:
|
||||
case common.KubernetesRelease1Dot7:
|
||||
default:
|
||||
return fmt.Errorf("Upgrade to Kubernetes %s is not supported", o.OrchestratorRelease)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateKeyVaultSecrets(secrets []KeyVaultSecrets, requireCertificateStore bool) error {
|
||||
for _, s := range secrets {
|
||||
if len(s.VaultCertificates) == 0 {
|
||||
|
|
|
@ -38,25 +38,20 @@ type AgentPoolTopology struct {
|
|||
UpgradedAgentVMs *[]compute.VirtualMachine
|
||||
}
|
||||
|
||||
// UpgradeCluster upgrades a cluster with Orchestrator version X
|
||||
// (or X.X or X.X.X) to version y (or Y.Y or X.X.X). RIght now
|
||||
// upgrades are supported for Kubernetes cluster only.
|
||||
// UpgradeCluster upgrades a cluster with Orchestrator version X.X to version Y.Y.
|
||||
// Right now upgrades are supported for Kubernetes cluster only.
|
||||
type UpgradeCluster struct {
|
||||
Translator *i18n.Translator
|
||||
ClusterTopology
|
||||
Client armhelpers.ACSEngineClient
|
||||
|
||||
UpgradeModel *api.UpgradeContainerService
|
||||
}
|
||||
|
||||
// MasterVMNamePrefix is the prefix for all master VM names for Kubernetes clusters
|
||||
const MasterVMNamePrefix = "k8s-master-"
|
||||
|
||||
// UpgradeCluster runs the workflow to upgrade a Kubernetes cluster.
|
||||
// UpgradeContainerService contains target state of the cluster that
|
||||
// the operation will drive towards.
|
||||
func (uc *UpgradeCluster) UpgradeCluster(subscriptionID uuid.UUID, resourceGroup string,
|
||||
cs *api.ContainerService, ucs *api.UpgradeContainerService, nameSuffix string) error {
|
||||
cs *api.ContainerService, nameSuffix string) error {
|
||||
uc.ClusterTopology = ClusterTopology{}
|
||||
uc.ResourceGroup = resourceGroup
|
||||
uc.DataModel = cs
|
||||
|
@ -65,42 +60,35 @@ func (uc *UpgradeCluster) UpgradeCluster(subscriptionID uuid.UUID, resourceGroup
|
|||
uc.UpgradedMasterVMs = &[]compute.VirtualMachine{}
|
||||
uc.AgentPools = make(map[string]*AgentPoolTopology)
|
||||
|
||||
uc.UpgradeModel = ucs
|
||||
|
||||
if err := uc.getClusterNodeStatus(subscriptionID, resourceGroup); err != nil {
|
||||
return uc.Translator.Errorf("Error while querying ARM for resources: %+v", err)
|
||||
}
|
||||
|
||||
var upgrader UpgradeWorkFlow
|
||||
log.Infoln(fmt.Sprintf("Upgrading to Kubernetes release %s", ucs.OrchestratorProfile.OrchestratorRelease))
|
||||
switch ucs.OrchestratorProfile.OrchestratorRelease {
|
||||
log.Infoln(fmt.Sprintf("Upgrading to Kubernetes release %s", uc.DataModel.Properties.OrchestratorProfile.OrchestratorRelease))
|
||||
switch uc.DataModel.Properties.OrchestratorProfile.OrchestratorRelease {
|
||||
case api.KubernetesRelease1Dot6:
|
||||
upgrader16 := &Kubernetes16upgrader{}
|
||||
upgrader16.Init(uc.Translator, uc.ClusterTopology, uc.UpgradeModel, uc.Client)
|
||||
upgrader16.Init(uc.Translator, uc.ClusterTopology, uc.Client)
|
||||
upgrader = upgrader16
|
||||
|
||||
case api.KubernetesRelease1Dot7:
|
||||
upgrader17 := &Kubernetes17upgrader{}
|
||||
upgrader17.Init(uc.Translator, uc.ClusterTopology, uc.UpgradeModel, uc.Client)
|
||||
upgrader17.Init(uc.Translator, uc.ClusterTopology, uc.Client)
|
||||
upgrader = upgrader17
|
||||
|
||||
default:
|
||||
return uc.Translator.Errorf("Upgrade to Kubernetes release: %s is not supported from release: %s",
|
||||
ucs.OrchestratorProfile.OrchestratorRelease,
|
||||
return uc.Translator.Errorf("Upgrade to Kubernetes release %s is not supported",
|
||||
uc.DataModel.Properties.OrchestratorProfile.OrchestratorRelease)
|
||||
}
|
||||
|
||||
if err := upgrader.ClusterPreflightCheck(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := upgrader.RunUpgrade(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infoln(fmt.Sprintf("Cluster upraded successfully to Kubernetes release %s, version: %s",
|
||||
ucs.OrchestratorProfile.OrchestratorRelease,
|
||||
ucs.OrchestratorProfile.OrchestratorVersion))
|
||||
uc.DataModel.Properties.OrchestratorProfile.OrchestratorRelease,
|
||||
uc.DataModel.Properties.OrchestratorProfile.OrchestratorVersion))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -110,10 +98,8 @@ func (uc *UpgradeCluster) getClusterNodeStatus(subscriptionID uuid.UUID, resourc
|
|||
return err
|
||||
}
|
||||
|
||||
orchestratorTypeVersion := fmt.Sprintf("%s:%s", uc.DataModel.Properties.OrchestratorProfile.OrchestratorType,
|
||||
targetOrchestratorTypeVersion := fmt.Sprintf("%s:%s", uc.DataModel.Properties.OrchestratorProfile.OrchestratorType,
|
||||
uc.DataModel.Properties.OrchestratorProfile.OrchestratorVersion)
|
||||
targetOrchestratorTypeVersion := fmt.Sprintf("%s:%s", uc.UpgradeModel.OrchestratorProfile.OrchestratorType,
|
||||
uc.UpgradeModel.OrchestratorProfile.OrchestratorVersion)
|
||||
|
||||
for _, vm := range *vmListResult.Value {
|
||||
if vm.Tags == nil {
|
||||
|
@ -122,25 +108,28 @@ func (uc *UpgradeCluster) getClusterNodeStatus(subscriptionID uuid.UUID, resourc
|
|||
}
|
||||
|
||||
vmOrchestratorTypeAndVersion := *(*vm.Tags)["orchestrator"]
|
||||
if vmOrchestratorTypeAndVersion == orchestratorTypeVersion {
|
||||
if vmOrchestratorTypeAndVersion != targetOrchestratorTypeVersion {
|
||||
if strings.Contains(*(vm.Name), MasterVMNamePrefix) {
|
||||
if !strings.Contains(*(vm.Name), uc.NameSuffix) {
|
||||
log.Infoln(fmt.Sprintf("Skipping VM: %s for upgrade as it does not belong to cluster with expected name suffix: %s",
|
||||
*vm.Name, uc.NameSuffix))
|
||||
continue
|
||||
}
|
||||
if err := uc.upgradable(vmOrchestratorTypeAndVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infoln(fmt.Sprintf("Master VM name: %s, orchestrator: %s (MasterVMs)", *vm.Name, vmOrchestratorTypeAndVersion))
|
||||
*uc.MasterVMs = append(*uc.MasterVMs, vm)
|
||||
} else {
|
||||
uc.addVMToAgentPool(vm, true)
|
||||
}
|
||||
} else if vmOrchestratorTypeAndVersion == targetOrchestratorTypeVersion {
|
||||
if !strings.Contains(*(vm.Name), uc.NameSuffix) {
|
||||
log.Infoln(fmt.Sprintf("Not adding VM: %s to upgraded list as it does not belong to cluster with expected name suffix: %s",
|
||||
*vm.Name, uc.NameSuffix))
|
||||
continue
|
||||
}
|
||||
if strings.Contains(*(vm.Name), MasterVMNamePrefix) {
|
||||
if !strings.Contains(*(vm.Name), uc.NameSuffix) {
|
||||
log.Infoln(fmt.Sprintf("Not adding VM: %s to upgraded list as it does not belong to cluster with expected name suffix: %s",
|
||||
*vm.Name, uc.NameSuffix))
|
||||
continue
|
||||
}
|
||||
log.Infoln(fmt.Sprintf("Master VM name: %s, orchestrator: %s (UpgradedMasterVMs)", *vm.Name, vmOrchestratorTypeAndVersion))
|
||||
*uc.UpgradedMasterVMs = append(*uc.UpgradedMasterVMs, vm)
|
||||
} else {
|
||||
|
@ -152,6 +141,35 @@ func (uc *UpgradeCluster) getClusterNodeStatus(subscriptionID uuid.UUID, resourc
|
|||
return nil
|
||||
}
|
||||
|
||||
func (uc *UpgradeCluster) upgradable(vmOrchestratorTypeAndVersion string) error {
|
||||
arr := strings.Split(vmOrchestratorTypeAndVersion, ":")
|
||||
if len(arr) != 2 {
|
||||
return fmt.Errorf("Unsupported orchestrator tag format %s", vmOrchestratorTypeAndVersion)
|
||||
}
|
||||
currentVer := arr[1]
|
||||
arr = strings.Split(currentVer, ".")
|
||||
if len(arr) != 3 {
|
||||
return fmt.Errorf("Unsupported orchestrator version format %s", currentVer)
|
||||
}
|
||||
currentRel := fmt.Sprintf("%s.%s", arr[0], arr[1])
|
||||
|
||||
csOrch := &api.OrchestratorProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorRelease: currentRel,
|
||||
OrchestratorVersion: currentVer,
|
||||
}
|
||||
orch, err := api.GetOrchestratorVersionProfile(csOrch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, up := range orch.Upgrades {
|
||||
if up.OrchestratorRelease == uc.DataModel.Properties.OrchestratorProfile.OrchestratorRelease {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("%s in non-upgradable to %s", vmOrchestratorTypeAndVersion, uc.DataModel.Properties.OrchestratorProfile.OrchestratorRelease)
|
||||
}
|
||||
|
||||
func (uc *UpgradeCluster) addVMToAgentPool(vm compute.VirtualMachine, isUpgradableVM bool) error {
|
||||
var poolIdentifier string
|
||||
var poolPrefix string
|
||||
|
|
|
@ -25,8 +25,10 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
})
|
||||
|
||||
It("Should return error message when failing to list VMs during upgrade operation", func() {
|
||||
cs := api.ContainerService{}
|
||||
ucs := api.UpgradeContainerService{}
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot5, 1, 1)
|
||||
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
|
@ -38,7 +40,7 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", &cs, &ucs, "12345678")
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("Error while querying ARM for resources: ListVirtualMachines failed"))
|
||||
|
||||
|
@ -49,11 +51,8 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
It("Should return error message when failing to detete VMs during upgrade operation", func() {
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot5, 1, 1)
|
||||
|
||||
ucs := api.UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &api.OrchestratorProfile{}
|
||||
ucs.OrchestratorProfile.OrchestratorType = api.Kubernetes
|
||||
ucs.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
ucs.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
|
@ -65,8 +64,7 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, &ucs, "12345678")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("DeleteVirtualMachine failed"))
|
||||
})
|
||||
|
@ -74,11 +72,8 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
It("Should return error message when failing to deploy template during upgrade operation", func() {
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot6, 1, 1)
|
||||
|
||||
ucs := api.UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &api.OrchestratorProfile{}
|
||||
ucs.OrchestratorProfile.OrchestratorType = api.Kubernetes
|
||||
ucs.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
ucs.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
|
@ -90,7 +85,7 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, &ucs, "12345678")
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("DeployTemplate failed"))
|
||||
})
|
||||
|
@ -98,11 +93,8 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
It("Should return error message when failing to get a virtual machine during upgrade operation", func() {
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot5, 1, 6)
|
||||
|
||||
ucs := api.UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &api.OrchestratorProfile{}
|
||||
ucs.OrchestratorProfile.OrchestratorType = api.Kubernetes
|
||||
ucs.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
ucs.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
|
@ -114,7 +106,7 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, &ucs, "12345678")
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("GetVirtualMachine failed"))
|
||||
})
|
||||
|
@ -122,11 +114,8 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
It("Should return error message when failing to get storage client during upgrade operation", func() {
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot5, 5, 1)
|
||||
|
||||
ucs := api.UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &api.OrchestratorProfile{}
|
||||
ucs.OrchestratorProfile.OrchestratorType = api.Kubernetes
|
||||
ucs.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
ucs.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
|
@ -138,7 +127,7 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, &ucs, "12345678")
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("GetStorageClient failed"))
|
||||
})
|
||||
|
@ -146,11 +135,8 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
It("Should return error message when failing to delete network interface during upgrade operation", func() {
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot5, 3, 2)
|
||||
|
||||
ucs := api.UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &api.OrchestratorProfile{}
|
||||
ucs.OrchestratorProfile.OrchestratorType = api.Kubernetes
|
||||
ucs.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
ucs.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
|
@ -162,7 +148,7 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, &ucs, "12345678")
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("DeleteNetworkInterface failed"))
|
||||
})
|
||||
|
@ -170,11 +156,8 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
It("Should return error message when failing on ClusterPreflightCheck operation", func() {
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot5, 3, 3)
|
||||
|
||||
ucs := api.UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &api.OrchestratorProfile{}
|
||||
ucs.OrchestratorProfile.OrchestratorType = api.Kubernetes
|
||||
ucs.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot7
|
||||
ucs.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot7]
|
||||
cs.Properties.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot7
|
||||
cs.Properties.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot7]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
|
@ -185,32 +168,9 @@ var _ = Describe("Upgrade Kubernetes cluster tests", func() {
|
|||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, &ucs, "12345678")
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("Upgrade to Kubernetes 1.7 is not supported from orchestrator release: 1.5"))
|
||||
})
|
||||
|
||||
It("Should return error message when failing on ClusterPreflightCheck operation", func() {
|
||||
cs := createContainerService("testcluster", api.KubernetesRelease1Dot7, 3, 3)
|
||||
|
||||
ucs := api.UpgradeContainerService{}
|
||||
ucs.OrchestratorProfile = &api.OrchestratorProfile{}
|
||||
ucs.OrchestratorProfile.OrchestratorType = api.Kubernetes
|
||||
ucs.OrchestratorProfile.OrchestratorRelease = api.KubernetesRelease1Dot6
|
||||
ucs.OrchestratorProfile.OrchestratorVersion = api.KubernetesReleaseToVersion[api.KubernetesRelease1Dot6]
|
||||
|
||||
uc := UpgradeCluster{
|
||||
Translator: &i18n.Translator{},
|
||||
}
|
||||
|
||||
mockClient := armhelpers.MockACSEngineClient{}
|
||||
uc.Client = &mockClient
|
||||
|
||||
subID, _ := uuid.FromString("DEC923E3-1EF1-4745-9516-37906D56DEC4")
|
||||
|
||||
err := uc.UpgradeCluster(subID, "TestRg", cs, &ucs, "12345678")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(err.Error()).To(Equal("Upgrade to Kubernetes 1.6 is not supported from orchestrator release: 1.7"))
|
||||
Expect(err.Error()).To(Equal("Error while querying ARM for resources: Kubernetes:1.5.7 in non-upgradable to 1.7"))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -15,28 +15,18 @@ import (
|
|||
type Upgrader struct {
|
||||
Translator *i18n.Translator
|
||||
ClusterTopology
|
||||
GoalStateDataModel *api.ContainerService
|
||||
UpgradeModel *api.UpgradeContainerService
|
||||
Client armhelpers.ACSEngineClient
|
||||
Client armhelpers.ACSEngineClient
|
||||
}
|
||||
|
||||
// Init initializes an upgrader struct
|
||||
func (ku *Upgrader) Init(translator *i18n.Translator, clusterTopology ClusterTopology, upgradeModel *api.UpgradeContainerService, client armhelpers.ACSEngineClient) {
|
||||
func (ku *Upgrader) Init(translator *i18n.Translator, clusterTopology ClusterTopology, client armhelpers.ACSEngineClient) {
|
||||
ku.Translator = translator
|
||||
ku.ClusterTopology = clusterTopology
|
||||
ku.UpgradeModel = upgradeModel
|
||||
ku.Client = client
|
||||
}
|
||||
|
||||
// RunUpgrade runs the upgrade pipeline
|
||||
func (ku *Upgrader) RunUpgrade() error {
|
||||
ku.GoalStateDataModel = ku.ClusterTopology.DataModel
|
||||
ku.GoalStateDataModel.Properties.OrchestratorProfile = &api.OrchestratorProfile{
|
||||
OrchestratorType: api.Kubernetes,
|
||||
OrchestratorRelease: ku.UpgradeModel.OrchestratorProfile.OrchestratorRelease,
|
||||
OrchestratorVersion: api.KubernetesReleaseToVersion[ku.UpgradeModel.OrchestratorProfile.OrchestratorRelease],
|
||||
}
|
||||
|
||||
if err := ku.upgradeMasterNodes(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -54,9 +44,9 @@ func (ku *Upgrader) Validate() error {
|
|||
}
|
||||
|
||||
func (ku *Upgrader) upgradeMasterNodes() error {
|
||||
log.Infoln(fmt.Sprintf("Master nodes StorageProfile: %s", ku.GoalStateDataModel.Properties.MasterProfile.StorageProfile))
|
||||
log.Infoln(fmt.Sprintf("Master nodes StorageProfile: %s", ku.ClusterTopology.DataModel.Properties.MasterProfile.StorageProfile))
|
||||
// Upgrade Master VMs
|
||||
templateMap, parametersMap, err := ku.generateUpgradeTemplate(ku.GoalStateDataModel)
|
||||
templateMap, parametersMap, err := ku.generateUpgradeTemplate(ku.ClusterTopology.DataModel)
|
||||
if err != nil {
|
||||
return ku.Translator.Errorf("error generating upgrade template: %s", err.Error())
|
||||
}
|
||||
|
@ -76,11 +66,11 @@ func (ku *Upgrader) upgradeMasterNodes() error {
|
|||
}
|
||||
upgradeMasterNode.TemplateMap = templateMap
|
||||
upgradeMasterNode.ParametersMap = parametersMap
|
||||
upgradeMasterNode.UpgradeContainerService = ku.GoalStateDataModel
|
||||
upgradeMasterNode.UpgradeContainerService = ku.ClusterTopology.DataModel
|
||||
upgradeMasterNode.ResourceGroup = ku.ClusterTopology.ResourceGroup
|
||||
upgradeMasterNode.Client = ku.Client
|
||||
|
||||
expectedMasterCount := ku.GoalStateDataModel.Properties.MasterProfile.Count
|
||||
expectedMasterCount := ku.ClusterTopology.DataModel.Properties.MasterProfile.Count
|
||||
mastersUpgradedCount := len(*ku.ClusterTopology.UpgradedMasterVMs)
|
||||
mastersToUgradeCount := expectedMasterCount - mastersUpgradedCount
|
||||
|
||||
|
@ -171,7 +161,7 @@ func (ku *Upgrader) upgradeMasterNodes() error {
|
|||
func (ku *Upgrader) upgradeAgentPools() error {
|
||||
for _, agentPool := range ku.ClusterTopology.AgentPools {
|
||||
// Upgrade Agent VMs
|
||||
templateMap, parametersMap, err := ku.generateUpgradeTemplate(ku.GoalStateDataModel)
|
||||
templateMap, parametersMap, err := ku.generateUpgradeTemplate(ku.ClusterTopology.DataModel)
|
||||
if err != nil {
|
||||
return ku.Translator.Errorf("error generating upgrade template: %s", err.Error())
|
||||
}
|
||||
|
@ -188,7 +178,7 @@ func (ku *Upgrader) upgradeAgentPools() error {
|
|||
}
|
||||
|
||||
var agentCount int
|
||||
for _, app := range ku.GoalStateDataModel.Properties.AgentPoolProfiles {
|
||||
for _, app := range ku.ClusterTopology.DataModel.Properties.AgentPoolProfiles {
|
||||
if app.Name == *agentPool.Name {
|
||||
agentCount = app.Count
|
||||
break
|
||||
|
@ -200,7 +190,7 @@ func (ku *Upgrader) upgradeAgentPools() error {
|
|||
}
|
||||
upgradeAgentNode.TemplateMap = templateMap
|
||||
upgradeAgentNode.ParametersMap = parametersMap
|
||||
upgradeAgentNode.UpgradeContainerService = ku.GoalStateDataModel
|
||||
upgradeAgentNode.UpgradeContainerService = ku.ClusterTopology.DataModel
|
||||
upgradeAgentNode.ResourceGroup = ku.ClusterTopology.ResourceGroup
|
||||
upgradeAgentNode.Client = ku.Client
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@ package kubernetesupgrade
|
|||
// UpgradeWorkFlow outlines various individual high level steps
|
||||
// that need to be run (one or more times) in the upgrade workflow.
|
||||
type UpgradeWorkFlow interface {
|
||||
ClusterPreflightCheck() error
|
||||
|
||||
// upgrade masters
|
||||
// upgrade agent nodes
|
||||
RunUpgrade() error
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
package kubernetesupgrade
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
)
|
||||
|
||||
// Compiler to verify QueueMessageProcessor implements OperationsProcessor
|
||||
var _ UpgradeWorkFlow = &Kubernetes16upgrader{}
|
||||
|
||||
|
@ -13,16 +7,3 @@ var _ UpgradeWorkFlow = &Kubernetes16upgrader{}
|
|||
type Kubernetes16upgrader struct {
|
||||
Upgrader
|
||||
}
|
||||
|
||||
// ClusterPreflightCheck does preflight check
|
||||
func (ku *Kubernetes16upgrader) ClusterPreflightCheck() error {
|
||||
// Check that current cluster is 1.5 or 1.6
|
||||
switch ku.DataModel.Properties.OrchestratorProfile.OrchestratorRelease {
|
||||
case api.KubernetesRelease1Dot5:
|
||||
case api.KubernetesRelease1Dot6:
|
||||
default:
|
||||
return fmt.Errorf("Upgrade to Kubernetes 1.6 is not supported from orchestrator release: %s",
|
||||
ku.DataModel.Properties.OrchestratorProfile.OrchestratorRelease)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
package kubernetesupgrade
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
)
|
||||
|
||||
// Compiler to verify QueueMessageProcessor implements OperationsProcessor
|
||||
var _ UpgradeWorkFlow = &Kubernetes17upgrader{}
|
||||
|
||||
|
@ -13,16 +7,3 @@ var _ UpgradeWorkFlow = &Kubernetes17upgrader{}
|
|||
type Kubernetes17upgrader struct {
|
||||
Upgrader
|
||||
}
|
||||
|
||||
// ClusterPreflightCheck does preflight check
|
||||
func (ku *Kubernetes17upgrader) ClusterPreflightCheck() error {
|
||||
// Check that current cluster is 1.6 or 1.7
|
||||
switch ku.DataModel.Properties.OrchestratorProfile.OrchestratorRelease {
|
||||
case api.KubernetesRelease1Dot6:
|
||||
case api.KubernetesRelease1Dot7:
|
||||
default:
|
||||
return fmt.Errorf("Upgrade to Kubernetes 1.7 is not supported from orchestrator release: %s",
|
||||
ku.DataModel.Properties.OrchestratorProfile.OrchestratorRelease)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче