Skip to content

Commit

Permalink
Restarting cilium daemonset on upgrade workflow to address upgrade is…
Browse files Browse the repository at this point in the history
…sue (#2057)

* Restarting cilium daemonset on upgrade workflow to address #1888

* moving cilium restart to cluster manager

* Fixing unit tests

* Improving unit test coverage

* Renaming daemonset restart method to be generic

* Renaming tests to decouple from cilium
  • Loading branch information
maxdrib authored May 7, 2022
1 parent 9a56d9d commit 8d734fa
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 1 deletion.
10 changes: 10 additions & 0 deletions pkg/clustermanager/cluster_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ type ClusterClient interface {
GetEksaVSphereMachineConfig(ctx context.Context, VSphereDatacenterName string, kubeconfigFile string, namespace string) (*v1alpha1.VSphereMachineConfig, error)
GetEksaCloudStackMachineConfig(ctx context.Context, cloudstackMachineConfigName string, kubeconfigFile string, namespace string) (*v1alpha1.CloudStackMachineConfig, error)
SetEksaControllerEnvVar(ctx context.Context, envVar, envVarVal, kubeconfig string) error
DaemonSetRolloutRestart(ctx context.Context, dsName, dsNamespace, kubeconfig string) error
CreateNamespace(ctx context.Context, kubeconfig string, namespace string) error
GetNamespace(ctx context.Context, kubeconfig string, namespace string) error
ValidateControlPlaneNodes(ctx context.Context, cluster *types.Cluster, clusterName string) error
Expand Down Expand Up @@ -395,6 +396,15 @@ func (c *ClusterManager) UpgradeCluster(ctx context.Context, managementCluster,
return fmt.Errorf("waiting for workload cluster control plane to be ready: %v", err)
}

if provider.Name() == constants.CloudStackProviderName {
// TODO: Move this logic to provider implementation: https://github.com/aws/eks-anywhere/issues/2061
logger.V(3).Info("Restarting cilium daemonset after upgrade")
err = c.clusterClient.DaemonSetRolloutRestart(ctx, "cilium", constants.KubeSystemNamespace, eksaMgmtCluster.KubeconfigFile)
if err != nil {
return fmt.Errorf("restarting cilium daemonset after upgrade: %v", err)
}
}

logger.V(3).Info("Waiting for workload cluster control plane replicas to be ready after upgrade")
err = c.waitForControlPlaneReplicasReady(ctx, managementCluster, newClusterSpec)
if err != nil {
Expand Down
40 changes: 40 additions & 0 deletions pkg/clustermanager/cluster_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ func TestClusterManagerUpgradeSelfManagedClusterSuccess(t *testing.T) {
}

tt := newSpecChangedTest(t)
tt.mocks.provider.EXPECT().Name().Return("test")
tt.mocks.client.EXPECT().GetEksaCluster(tt.ctx, tt.cluster, tt.clusterSpec.Cluster.Name).Return(tt.oldClusterConfig, nil)
tt.mocks.client.EXPECT().GetBundles(tt.ctx, tt.cluster.KubeconfigFile, tt.cluster.Name, "").Return(test.Bundles(t), nil)
tt.mocks.client.EXPECT().GetEksdRelease(tt.ctx, gomock.Any(), constants.EksaSystemNamespace, gomock.Any())
Expand Down Expand Up @@ -502,6 +503,7 @@ func TestClusterManagerUpgradeWorkloadClusterSuccess(t *testing.T) {
}

tt := newSpecChangedTest(t)
tt.mocks.provider.EXPECT().Name().Return("test")
tt.mocks.client.EXPECT().GetEksaCluster(tt.ctx, mCluster, mgmtClusterName).Return(tt.oldClusterConfig, nil)
tt.mocks.client.EXPECT().GetBundles(tt.ctx, mCluster.KubeconfigFile, mCluster.Name, "").Return(test.Bundles(t), nil)
tt.mocks.client.EXPECT().GetEksdRelease(tt.ctx, gomock.Any(), constants.EksaSystemNamespace, gomock.Any())
Expand All @@ -524,6 +526,43 @@ func TestClusterManagerUpgradeWorkloadClusterSuccess(t *testing.T) {
}
}

func TestClusterManagerUpgradeCloudStackWorkloadClusterSuccess(t *testing.T) {
mgmtClusterName := "cluster-name"
workClusterName := "cluster-name-w"

mCluster := &types.Cluster{
Name: mgmtClusterName,
ExistingManagement: true,
}
wCluster := &types.Cluster{
Name: workClusterName,
}

tt := newSpecChangedTest(t)
tt.mocks.provider.EXPECT().Name().Return(constants.CloudStackProviderName)
tt.mocks.client.EXPECT().GetEksaCluster(tt.ctx, mCluster, mgmtClusterName).Return(tt.oldClusterConfig, nil)
tt.mocks.client.EXPECT().GetBundles(tt.ctx, mCluster.KubeconfigFile, mCluster.Name, "").Return(test.Bundles(t), nil)
tt.mocks.client.EXPECT().GetEksdRelease(tt.ctx, gomock.Any(), constants.EksaSystemNamespace, gomock.Any())
tt.mocks.provider.EXPECT().GenerateCAPISpecForUpgrade(tt.ctx, mCluster, mCluster, tt.clusterSpec, tt.clusterSpec.DeepCopy())
tt.mocks.client.EXPECT().ApplyKubeSpecFromBytesWithNamespace(tt.ctx, mCluster, test.OfType("[]uint8"), constants.EksaSystemNamespace).Times(2)
tt.mocks.provider.EXPECT().RunPostControlPlaneUpgrade(tt.ctx, tt.clusterSpec, tt.clusterSpec, wCluster, mCluster)
tt.mocks.client.EXPECT().WaitForControlPlaneReady(tt.ctx, mCluster, "60m", mgmtClusterName).MaxTimes(2)
tt.mocks.client.EXPECT().WaitForControlPlaneNotReady(tt.ctx, mCluster, "1m", mgmtClusterName)
tt.mocks.client.EXPECT().GetMachines(tt.ctx, mCluster, mCluster.Name).Return([]types.Machine{}, nil).Times(2)
tt.mocks.provider.EXPECT().MachineDeploymentsToDelete(mCluster, tt.clusterSpec, tt.clusterSpec.DeepCopy()).Return([]string{})
tt.mocks.client.EXPECT().WaitForDeployment(tt.ctx, mCluster, "30m", "Available", gomock.Any(), gomock.Any()).MaxTimes(10)
tt.mocks.client.EXPECT().ValidateControlPlaneNodes(tt.ctx, mCluster, mCluster.Name).Return(nil)
tt.mocks.client.EXPECT().ValidateWorkerNodes(tt.ctx, mCluster.Name, mCluster.KubeconfigFile).Return(nil)
tt.mocks.provider.EXPECT().GetDeployments()
tt.mocks.writer.EXPECT().Write(mgmtClusterName+"-eks-a-cluster.yaml", gomock.Any(), gomock.Not(gomock.Nil()))
tt.mocks.client.EXPECT().GetEksaOIDCConfig(tt.ctx, tt.clusterSpec.Cluster.Spec.IdentityProviderRefs[0].Name, mCluster.KubeconfigFile, tt.clusterSpec.Cluster.Namespace).Return(nil, nil)
tt.mocks.client.EXPECT().DaemonSetRolloutRestart(tt.ctx, "cilium", constants.KubeSystemNamespace, tt.cluster.KubeconfigFile)

if err := tt.clusterManager.UpgradeCluster(tt.ctx, mCluster, wCluster, tt.clusterSpec, tt.mocks.provider); err != nil {
t.Errorf("ClusterManager.UpgradeCluster() error = %v, wantErr nil", err)
}
}

func TestClusterManagerUpgradeWorkloadClusterWaitForMachinesTimeout(t *testing.T) {
ctx := context.Background()
clusterName := "cluster-name"
Expand Down Expand Up @@ -610,6 +649,7 @@ func TestClusterManagerUpgradeWorkloadClusterWaitForCAPITimeout(t *testing.T) {
}

tt := newSpecChangedTest(t)
tt.mocks.provider.EXPECT().Name().Return("test")
tt.mocks.client.EXPECT().GetEksaCluster(tt.ctx, tt.cluster, tt.clusterSpec.Cluster.Name).Return(tt.oldClusterConfig, nil)
tt.mocks.client.EXPECT().GetBundles(tt.ctx, tt.cluster.KubeconfigFile, tt.cluster.Name, "").Return(test.Bundles(t), nil)
tt.mocks.client.EXPECT().GetEksdRelease(tt.ctx, gomock.Any(), constants.EksaSystemNamespace, gomock.Any())
Expand Down
14 changes: 14 additions & 0 deletions pkg/clustermanager/mocks/client_and_networking.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions pkg/executables/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,18 @@ func (k *Kubectl) ValidateEKSAClustersCRD(ctx context.Context, cluster *types.Cl
return nil
}

func (k *Kubectl) DaemonSetRolloutRestart(ctx context.Context, dsName, dsNamespace, kubeconfig string) error {
params := []string{
"rollout", "restart", "ds", dsName,
"--kubeconfig", kubeconfig, "--namespace", dsNamespace,
}
_, err := k.Execute(ctx, params...)
if err != nil {
return fmt.Errorf("restarting %s daemonset in namespace %s: %v", dsName, dsNamespace, err)
}
return nil
}

func (k *Kubectl) SetEksaControllerEnvVar(ctx context.Context, envVar, envVarVal, kubeconfig string) error {
params := []string{
"set", "env", "deployment/eksa-controller-manager", fmt.Sprintf("%s=%s", envVar, envVarVal),
Expand Down
34 changes: 33 additions & 1 deletion pkg/executables/kubectl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,39 @@ func TestKubectlSetControllerEnvVarSuccess(t *testing.T) {

err := k.SetEksaControllerEnvVar(ctx, envVar, envVarValue, cluster.KubeconfigFile)
if err != nil {
t.Fatalf("Kubectl.GetApiServerUrl() error = %v, want nil", err)
t.Fatalf("Kubectl.DaemonSetRolloutRestart() error = %v, want nil", err)
}
}

func TestKubectlDaemonSetRolloutRestartSuccess(t *testing.T) {
k, ctx, cluster, e := newKubectl(t)
e.EXPECT().Execute(
ctx,
[]string{
"rollout", "restart", "ds", "cilium",
"--kubeconfig", cluster.KubeconfigFile, "--namespace", constants.KubeSystemNamespace,
},
).Return(bytes.Buffer{}, nil)

err := k.DaemonSetRolloutRestart(ctx, "cilium", constants.KubeSystemNamespace, cluster.KubeconfigFile)
if err != nil {
t.Fatalf("Kubectl.DaemonSetRolloutRestart() error = %v, want nil", err)
}
}

func TestKubectlDaemonSetRolloutRestartError(t *testing.T) {
k, ctx, cluster, e := newKubectl(t)
e.EXPECT().Execute(
ctx,
[]string{
"rollout", "restart", "ds", "cilium",
"--kubeconfig", cluster.KubeconfigFile, "--namespace", constants.KubeSystemNamespace,
},
).Return(bytes.Buffer{}, fmt.Errorf("error"))

err := k.DaemonSetRolloutRestart(ctx, "cilium", constants.KubeSystemNamespace, cluster.KubeconfigFile)
if err == nil {
t.Fatalf("Kubectl.DaemonSetRolloutRestart() expected error, but was nil")
}
}

Expand Down

0 comments on commit 8d734fa

Please sign in to comment.