Skip to content

Commit

Permalink
Upgrade hubble relay with cli
Browse files Browse the repository at this point in the history
If hubble relay deployment is present on the cluster, try to upgrade it if needed

Signed-off-by: Alexander Demichev <[email protected]>
  • Loading branch information
alexander-demicev authored and michi-covalent committed May 12, 2022
1 parent bc8188c commit 5e2966c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 15 deletions.
1 change: 1 addition & 0 deletions defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
OperatorServiceAccountName = "cilium-operator"
OperatorClusterRoleName = "cilium-operator"
OperatorSecretsRoleName = "cilium-operator-secrets"
OperatorContainerName = "cilium-operator"
OperatorDeploymentName = "cilium-operator"
OperatorResourceQuota = "cilium-operator-resource-quota"
OperatorImage = "quay.io/cilium/operator-generic"
Expand Down
7 changes: 6 additions & 1 deletion install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ type Parameters struct {
Version string
AgentImage string
OperatorImage string
RelayImage string
InheritCA string
Wait bool
WaitDuration time.Duration
Expand Down Expand Up @@ -289,7 +290,7 @@ func (p *Parameters) validate() error {

p.configOverwrites[t[0]] = t[1]
}
if p.AgentImage != "" || p.OperatorImage != "" {
if p.AgentImage != "" || p.OperatorImage != "" || p.RelayImage != "" {
return nil
} else if !utils.CheckVersion(p.Version) && p.Version != "" {
return fmt.Errorf("invalid syntax %q for image tag", p.Version)
Expand All @@ -314,6 +315,10 @@ func (k *K8sInstaller) fqOperatorImage(imagePathMode utils.ImagePathMode) string
return utils.BuildImagePath(k.params.OperatorImage, k.params.Version, defaultImage, defaults.Version, imagePathMode)
}

func (k *K8sInstaller) fqRelayImage(imagePathMode utils.ImagePathMode) string {
return utils.BuildImagePath(k.params.RelayImage, k.params.Version, defaults.RelayImage, defaults.Version, imagePathMode)
}

func NewK8sInstaller(client k8sInstallerImplementation, p Parameters) (*K8sInstaller, error) {
if err := (&p).validate(); err != nil {
return nil, fmt.Errorf("invalid parameters: %w", err)
Expand Down
67 changes: 53 additions & 14 deletions install/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"strings"

appsv1 "k8s.io/api/apps/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

Expand Down Expand Up @@ -35,19 +37,13 @@ func (k *K8sInstaller) Upgrade(ctx context.Context) error {

var patched int

if deployment.Spec.Template.Spec.Containers[0].Image == k.fqOperatorImage(utils.ImagePathIncludeDigest) ||
deployment.Spec.Template.Spec.Containers[0].Image == k.fqOperatorImage(utils.ImagePathExcludeDigest) {
k.Log("✅ cilium-operator is already up to date")
} else {
k.Log("🚀 Upgrading cilium-operator to version %s...", k.fqOperatorImage(utils.ImagePathExcludeDigest))
patch := []byte(`{"spec":{"template":{"spec":{"containers":[{"name": "cilium-operator", "image":"` + k.fqOperatorImage(utils.ImagePathIncludeDigest) + `"}]}}}}`)

_, err = k.client.PatchDeployment(ctx, k.params.Namespace, defaults.OperatorDeploymentName, types.StrategicMergePatchType, patch, metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("unable to patch Deployment %s with patch %q: %w", defaults.OperatorDeploymentName, patch, err)
}

patched++
if err = upgradeDeployment(ctx, k, upgradeDeploymentParams{
deployment: deployment,
imageIncludeDigest: k.fqOperatorImage(utils.ImagePathIncludeDigest),
imageExcludeDigest: k.fqOperatorImage(utils.ImagePathExcludeDigest),
containerName: defaults.OperatorContainerName,
}, &patched); err != nil {
return err
}

agentImage := k.fqAgentImage(utils.ImagePathIncludeDigest)
Expand Down Expand Up @@ -78,13 +74,29 @@ func (k *K8sInstaller) Upgrade(ctx context.Context) error {
patched++
}

hubbleRelayDeployment, err := k.client.GetDeployment(ctx, k.params.Namespace, defaults.RelayDeploymentName, metav1.GetOptions{})
if err != nil && !k8serrors.IsNotFound(err) {
return fmt.Errorf("unable to retrieve Deployment of %s: %w", defaults.RelayDeploymentName, err)
}

if err == nil { // only update if hubble relay deployment was found on the cluster
if err = upgradeDeployment(ctx, k, upgradeDeploymentParams{
deployment: hubbleRelayDeployment,
imageIncludeDigest: k.fqRelayImage(utils.ImagePathIncludeDigest),
imageExcludeDigest: k.fqRelayImage(utils.ImagePathExcludeDigest),
containerName: defaults.RelayContainerName,
}, &patched); err != nil {
return err
}
}

if patched > 0 && k.params.Wait {
k.Log("⌛ Waiting for Cilium to be upgraded...")
collector, err := status.NewK8sStatusCollector(k.client, status.K8sStatusParameters{
Namespace: k.params.Namespace,
Wait: true,
WaitDuration: k.params.WaitDuration,
WarningFreePods: []string{defaults.AgentDaemonSetName, defaults.OperatorDeploymentName},
WarningFreePods: []string{defaults.AgentDaemonSetName, defaults.OperatorDeploymentName, defaults.RelayDeploymentName},
})
if err != nil {
return err
Expand All @@ -99,3 +111,30 @@ func (k *K8sInstaller) Upgrade(ctx context.Context) error {

return nil
}

type upgradeDeploymentParams struct {
deployment *appsv1.Deployment
imageIncludeDigest string
imageExcludeDigest string
containerName string
}

func upgradeDeployment(ctx context.Context, k *K8sInstaller, params upgradeDeploymentParams, patched *int) error {
if params.deployment.Spec.Template.Spec.Containers[0].Image == params.imageIncludeDigest ||
params.deployment.Spec.Template.Spec.Containers[0].Image == params.imageExcludeDigest {
k.Log("✅ %s is already up to date", params.deployment.Name)
return nil
}

k.Log("🚀 Upgrading %s to version %s...", params.deployment.Name, params.imageExcludeDigest)
containerPath := fmt.Sprintf(`{"spec":{"template":{"spec":{"containers":[{"name": "%s", "image":"`, params.containerName)
patch := []byte(containerPath + params.imageIncludeDigest + `"}]}}}}`)

_, err := k.client.PatchDeployment(ctx, k.params.Namespace, params.deployment.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("unable to patch Deployment %s with patch %q: %w", params.deployment.Name, patch, err)
}

*patched++
return nil
}
1 change: 1 addition & 0 deletions internal/cli/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ cilium upgrade --version %s
cmd.Flags().DurationVar(&params.WaitDuration, "wait-duration", defaults.StatusWaitDuration, "Maximum time to wait for status")
cmd.Flags().StringVar(&params.AgentImage, "agent-image", "", "Image path to use for Cilium agent")
cmd.Flags().StringVar(&params.OperatorImage, "operator-image", "", "Image path to use for Cilium operator")
cmd.Flags().StringVar(&params.RelayImage, "hubble-relay-image", "", "Image path to use for Hubble Relay")

return cmd
}

0 comments on commit 5e2966c

Please sign in to comment.