Skip to content

Commit

Permalink
Change around of caas provider operator upgrade logic
Browse files Browse the repository at this point in the history
  • Loading branch information
tlm committed Jul 2, 2020
1 parent ff903d9 commit f187d71
Show file tree
Hide file tree
Showing 14 changed files with 1,062 additions and 569 deletions.
14 changes: 5 additions & 9 deletions apiserver/facades/controller/caasoperatorupgrader/upgrader.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/juju/juju/apiserver/facade"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/caas"
"github.com/juju/juju/environs/bootstrap"
"github.com/juju/juju/state/stateenvirons"
)

Expand Down Expand Up @@ -43,7 +42,9 @@ func NewCAASOperatorUpgraderAPI(
authorizer facade.Authorizer,
broker caas.Upgrader,
) (*API, error) {
if !authorizer.AuthController() && !authorizer.AuthApplicationAgent() && !authorizer.AuthModelAgent() {
if !authorizer.AuthController() &&
!authorizer.AuthApplicationAgent() &&
!authorizer.AuthModelAgent() {
return nil, common.ErrPerm
}
return &API{
Expand All @@ -64,14 +65,9 @@ func (api *API) UpgradeOperator(arg params.KubernetesUpgradeArg) (params.ErrorRe
if !api.auth.AuthOwner(tag) {
return serverErr(common.ErrPerm), nil
}
appName := tag.Id()

// Nodes representing controllers really mean the controller operator.
if tag.Kind() == names.MachineTagKind || tag.Kind() == names.ControllerAgentTagKind {
appName = bootstrap.ControllerModelName
}
logger.Debugf("upgrading caas app %v", appName)
err = api.broker.Upgrade(appName, arg.Version)
logger.Debugf("upgrading caas agent for %s", tag)
err = api.broker.Upgrade(arg.AgentTag, arg.Version)
if err != nil {
return serverErr(err), nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (s *CAASProvisionerSuite) TestUpgradeOperator(c *gc.C) {
})
c.Assert(err, jc.ErrorIsNil)
c.Assert(result.Error, gc.IsNil)
s.broker.CheckCall(c, 0, "Upgrade", "app", vers)
s.broker.CheckCall(c, 0, "Upgrade", s.authorizer.Tag.String(), vers)
}

func (s *CAASProvisionerSuite) assertUpgradeController(c *gc.C, tag names.Tag) {
Expand All @@ -74,7 +74,7 @@ func (s *CAASProvisionerSuite) assertUpgradeController(c *gc.C, tag names.Tag) {
})
c.Assert(err, jc.ErrorIsNil)
c.Assert(result.Error, gc.IsNil)
s.broker.CheckCall(c, 0, "Upgrade", "controller", vers)
s.broker.CheckCall(c, 0, "Upgrade", tag.String(), vers)
}

func (s *CAASProvisionerSuite) TestUpgradeLegacyController(c *gc.C) {
Expand Down
48 changes: 48 additions & 0 deletions caas/kubernetes/provider/controller_upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package provider

import (
"github.com/juju/names/v4"
"github.com/juju/version"
"k8s.io/client-go/kubernetes"

"github.com/juju/juju/environs/bootstrap"
)

type upgradeCAASControllerBridge struct {
clientFn func() kubernetes.Interface
namespaceFn func() string
}

// UpgradeCAASControllerBroker describes the interface needed for upgrading
// Juju Kubernetes controllers
type UpgradeCAASControllerBroker interface {
// Client returns a Kubernetes client associated with the current broker's
// cluster
Client() kubernetes.Interface

// Namespace returns the targeted Kubernetes namespace for this broker
Namespace() string
}

func (u *upgradeCAASControllerBridge) Client() kubernetes.Interface {
return u.clientFn()
}

func (u *upgradeCAASControllerBridge) Namespace() string {
return u.namespaceFn()
}

func controllerUpgrade(appName string, vers version.Number, broker UpgradeCAASControllerBroker) error {
return upgradeStatefulSet(appName, "", vers, broker.Client().AppsV1().StatefulSets(broker.Namespace()))
}

func (k *kubernetesClient) upgradeController(agentTag names.Tag, vers version.Number) error {
broker := &upgradeCAASControllerBridge{
clientFn: k.client,
namespaceFn: k.GetCurrentNamespace,
}
return controllerUpgrade(bootstrap.ControllerModelName, vers, broker)
}
97 changes: 97 additions & 0 deletions caas/kubernetes/provider/controller_upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package provider

import (
"fmt"

"github.com/juju/errors"
jc "github.com/juju/testing/checkers"
"github.com/juju/version"
gc "gopkg.in/check.v1"
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"

"github.com/juju/juju/cloudconfig/podcfg"
)

// DummyUpgradeCAASController implements UpgradeCAASControllerBroker for the
// purpose of testing.
type dummyUpgradeCAASController struct {
client *fake.Clientset
}

type ControllerUpgraderSuite struct {
broker *dummyUpgradeCAASController
}

var _ = gc.Suite(&ControllerUpgraderSuite{})

func (d *dummyUpgradeCAASController) Client() kubernetes.Interface {
return d.client
}

func (d *dummyUpgradeCAASController) Namespace() string {
return "test"
}

func (s *ControllerUpgraderSuite) SetUpTest(c *gc.C) {
s.broker = &dummyUpgradeCAASController{
client: fake.NewSimpleClientset(),
}
}

func (s *ControllerUpgraderSuite) TestControllerUpgrade(c *gc.C) {
var (
appName = JujuControllerStackName
oldImagePath = fmt.Sprintf("%s/%s:9.9.8", podcfg.JujudOCINamespace, podcfg.JujudOCIName)
newImagePath = fmt.Sprintf("%s/%s:9.9.9", podcfg.JujudOCINamespace, podcfg.JujudOCIName)
)
_, err := s.broker.Client().AppsV1().StatefulSets(s.broker.Namespace()).Create(
&apps.StatefulSet{
ObjectMeta: meta.ObjectMeta{
Name: appName,
},
Spec: apps.StatefulSetSpec{
Selector: &meta.LabelSelector{
MatchLabels: map[string]string{
"match-label": "true",
},
},
Template: core.PodTemplateSpec{
Spec: core.PodSpec{
Containers: []core.Container{
{
Name: "jujud",
Image: oldImagePath,
},
},
},
},
},
})
c.Assert(err, jc.ErrorIsNil)

c.Assert(controllerUpgrade(appName, version.MustParse("9.9.9"), s.broker), jc.ErrorIsNil)

ss, err := s.broker.Client().AppsV1().StatefulSets(s.broker.Namespace()).
Get(appName, meta.GetOptions{})
c.Assert(err, jc.ErrorIsNil)
c.Assert(ss.Spec.Template.Spec.Containers[0].Image, gc.Equals, newImagePath)

c.Assert(ss.Annotations[labelVersion], gc.Equals, version.MustParse("9.9.9").String())
c.Assert(ss.Spec.Template.Annotations[labelVersion], gc.Equals, version.MustParse("9.9.9").String())
}

func (s *ControllerUpgraderSuite) TestControllerDoesNotExist(c *gc.C) {
var (
appName = JujuControllerStackName
)
err := controllerUpgrade(appName, version.MustParse("9.9.9"), s.broker)
c.Assert(err, gc.NotNil)
c.Assert(errors.IsNotFound(err), jc.IsTrue)
}
48 changes: 48 additions & 0 deletions caas/kubernetes/provider/modeloperator_upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package provider

import (
"github.com/juju/names/v4"
"github.com/juju/version"
"k8s.io/client-go/kubernetes"
)

type upgradeCAASModelOperatorBridge struct {
clientFn func() kubernetes.Interface
namespaceFn func() string
}

type UpgradeCAASModelOperatorBroker interface {
// Client returns a Kubernetes client associated with the current broker's
// cluster
Client() kubernetes.Interface

// Namespace returns the targeted Kubernetes namespace for this broker
Namespace() string
}

func (u *upgradeCAASModelOperatorBridge) Client() kubernetes.Interface {
return u.clientFn()
}

func modelOperatorUpgrade(
operatorName string,
vers version.Number,
broker UpgradeCAASModelOperatorBroker) error {
return upgradeDeployment(operatorName, "", vers,
broker.Client().AppsV1().Deployments(broker.Namespace()))
}

func (u *upgradeCAASModelOperatorBridge) Namespace() string {
return u.namespaceFn()
}

func (k *kubernetesClient) upgradeModelOperator(agentTag names.Tag, vers version.Number) error {
broker := &upgradeCAASModelOperatorBridge{
clientFn: k.client,
namespaceFn: k.GetCurrentNamespace,
}
return modelOperatorUpgrade(modelOperatorName, vers, broker)
}
85 changes: 85 additions & 0 deletions caas/kubernetes/provider/modeloperator_upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package provider

import (
"fmt"

jc "github.com/juju/testing/checkers"
"github.com/juju/version"
gc "gopkg.in/check.v1"
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"

"github.com/juju/juju/cloudconfig/podcfg"
)

type dummyUpgradeCAASModel struct {
client *fake.Clientset
}

type modelUpgraderSuite struct {
broker *dummyUpgradeCAASModel
}

var _ = gc.Suite(&modelUpgraderSuite{})

func (d *dummyUpgradeCAASModel) Client() kubernetes.Interface {
return d.client
}

func (d *dummyUpgradeCAASModel) Namespace() string {
return "test"
}

func (s *modelUpgraderSuite) SetUpTest(c *gc.C) {
s.broker = &dummyUpgradeCAASModel{
client: fake.NewSimpleClientset(),
}
}

func (s *modelUpgraderSuite) TestModelOperatorUpgrade(c *gc.C) {
var (
operatorName = modelOperatorName
oldImagePath = fmt.Sprintf("%s/%s:9.9.8", podcfg.JujudOCINamespace, podcfg.JujudOCIName)
newImagePath = fmt.Sprintf("%s/%s:9.9.9", podcfg.JujudOCINamespace, podcfg.JujudOCIName)
)

_, err := s.broker.Client().AppsV1().Deployments(s.broker.Namespace()).Create(
&apps.Deployment{
ObjectMeta: meta.ObjectMeta{
Name: operatorName,
},
Spec: apps.DeploymentSpec{
Selector: &meta.LabelSelector{
MatchLabels: map[string]string{
"match-label": "true",
},
},
Template: core.PodTemplateSpec{
Spec: core.PodSpec{
Containers: []core.Container{
{
Name: "jujud",
Image: oldImagePath,
},
},
},
},
},
})
c.Assert(err, jc.ErrorIsNil)

c.Assert(modelOperatorUpgrade(operatorName, version.MustParse("9.9.9"), s.broker), jc.ErrorIsNil)
de, err := s.broker.Client().AppsV1().Deployments(s.broker.Namespace()).
Get(operatorName, meta.GetOptions{})
c.Assert(err, jc.ErrorIsNil)
c.Assert(de.Spec.Template.Spec.Containers[0].Image, gc.Equals, newImagePath)

c.Assert(de.Annotations[labelVersion], gc.Equals, version.MustParse("9.9.9").String())
c.Assert(de.Spec.Template.Annotations[labelVersion], gc.Equals, version.MustParse("9.9.9").String())
}
Loading

0 comments on commit f187d71

Please sign in to comment.