Skip to content

Commit

Permalink
switch to using dynamicclient to retrieve rollouts
Browse files Browse the repository at this point in the history
Signed-off-by: Jonathan West <jonwest@redhat.com>
  • Loading branch information
jgwest committed May 7, 2024
1 parent 816c081 commit 905ece0
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 5 deletions.
4 changes: 2 additions & 2 deletions controllers/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (r *RolloutManagerReconciler) reconcileConfigMap(ctx context.Context, cr *r
},
},
}
trafficRouterPlugins := []PluginItem{
trafficRouterPlugins := []pluginItem{
{
Name: OpenShiftRolloutPluginName,
Location: r.OpenShiftRoutePluginLocation,
Expand All @@ -55,7 +55,7 @@ func (r *RolloutManagerReconciler) reconcileConfigMap(ctx context.Context, cr *r
return fmt.Errorf("failed to get the serviceAccount associated with %s: %w", desiredConfigMap.Name, err)
}

var actualTrafficRouterPlugins []PluginItem
var actualTrafficRouterPlugins []pluginItem
if err = yaml.Unmarshal([]byte(actualConfigMap.Data[TrafficRouterPluginConfigMapKey]), &actualTrafficRouterPlugins); err != nil {
return fmt.Errorf("failed to unmarshal traffic router plugins from ConfigMap: %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion controllers/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ var _ = Describe("ConfigMap Test", func() {
Expect(fetchedConfigMap.Data[TrafficRouterPluginConfigMapKey]).ToNot(ContainSubstring("test/plugin"))

By("adding a new trafficRouter plugin to test the update plugin logic")
trafficRouterPlugins := []PluginItem{
trafficRouterPlugins := []pluginItem{
{
Name: "test/plugin",
Location: "https://test-path",
Expand Down
4 changes: 3 additions & 1 deletion controllers/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ const (
UnsupportedRolloutManagerNamespaceScoped = "when Subscription has environment variable NAMESPACE_SCOPED_ARGO_ROLLOUTS set to False, there may not exist any namespace-scoped RolloutManagers: only a single cluster-scoped RolloutManager is supported"
)

type PluginItem struct {
// pluginItem is a clone of PluginItem from "github.com/argoproj/argo-rollouts/utils/plugin/types"
// We clone it here, to avoid a dependency on argo-rollouts.
type pluginItem struct {
Name string `json:"name" yaml:"name"`
Location string `json:"location" yaml:"location"`
Sha256 string `json:"sha256" yaml:"sha256"`
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
k8s.io/apimachinery v0.28.3
k8s.io/client-go v0.28.3
sigs.k8s.io/controller-runtime v0.16.3
sigs.k8s.io/yaml v1.3.0
)

require (
Expand Down Expand Up @@ -71,5 +72,4 @@ require (
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
10 changes: 10 additions & 0 deletions tests/e2e/fixture/fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -149,6 +150,15 @@ func (cleaner *Cleaner) deleteNamespace(namespaceParam string) error {
return nil
}

func GetDynamicClient() (*dynamic.DynamicClient, error) {
config, err := getSystemKubeConfig()
if err != nil {
return nil, err
}

return dynamic.NewForConfig(config)
}

func GetE2ETestKubeClient() (client.Client, *runtime.Scheme, error) {
config, err := getSystemKubeConfig()
if err != nil {
Expand Down
137 changes: 137 additions & 0 deletions tests/e2e/fixture/rollouts/fixture.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package rollouts

import (
"context"

"github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/yaml"
)

var rolloutGVR = schema.GroupVersionResource{
Group: "argoproj.io",
Version: "v1alpha1",
Resource: "rollouts",
}

func buildGenericRolloutResource(name, namespace, activeService, previewService string) string {

rolloutStr := `
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: ` + name + `
namespace: ` + namespace + `
spec:
replicas: 2
revisionHistoryLimit: 2
selector:
matchLabels:
app: test-argo-app
strategy:
blueGreen:
activeService: ` + activeService + `
autoPromotionEnabled: false
previewService: ` + previewService + `
template:
metadata:
labels:
app: test-argo-app
spec:
containers:
- image: docker.io/kostiscodefresh/gitops-canary-app:v1.0
name: webserver-simple
ports:
- containerPort: 8080
name: http
protocol: TCP
resources: {}`

return rolloutStr
}

func CreateArgoRollout(ctx context.Context, name, namespace, activeService, previewService string) (string, error) {

dynclient, err := fixture.GetDynamicClient()
if err != nil {
return "", err
}

rolloutStr := buildGenericRolloutResource(name, namespace, activeService, previewService)

var un unstructured.Unstructured
if err := yaml.UnmarshalStrict([]byte(rolloutStr), &un, yaml.DisallowUnknownFields); err != nil {
return "", err
}

if _, err := dynclient.Resource(rolloutGVR).Namespace(namespace).Create(ctx, &un, metav1.CreateOptions{}); err != nil {
return "", err
}

return rolloutStr, nil
}

func GetArgoRollout(ctx context.Context, name, namespace string) (*unstructured.Unstructured, error) {

dynclient, err := fixture.GetDynamicClient()
if err != nil {
return nil, err
}

return dynclient.Resource(rolloutGVR).Namespace(namespace).Get(ctx, name, metav1.GetOptions{})

}

func DeleteArgoRollout(ctx context.Context, name, namespace string) error {

dynclient, err := fixture.GetDynamicClient()
if err != nil {
return err
}

return dynclient.Resource(rolloutGVR).Namespace(namespace).Delete(ctx, name, metav1.DeleteOptions{})
}

func HasEmptyStatus(ctx context.Context, name, namespace string) (bool, error) {

rollout, err := GetArgoRollout(ctx, name, namespace)
if err != nil {
return false, err
}

mapVal := rollout.UnstructuredContent()

if mapVal["status"] == nil {
return true, nil
}

statusMapVal := (mapVal["status"]).(map[string]interface{})

return len(statusMapVal) == 0, nil
}

func HasStatusPhase(ctx context.Context, name, namespace string, expectedPhase string) (bool, error) {

rollout, err := GetArgoRollout(ctx, name, namespace)
if err != nil {
return false, err
}

mapVal := rollout.UnstructuredContent()

if mapVal["status"] == nil {
return false, nil
}

statusMapVal := (mapVal["status"]).(map[string]interface{})

if statusMapVal["phase"] == nil {
return false, nil
}

return (statusMapVal["phase"]).(string) == expectedPhase, nil

}
56 changes: 56 additions & 0 deletions tests/e2e/namespace-scoped/namespace_scoped_rollouts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package e2e

import (
"context"
"fmt"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -10,6 +11,7 @@ import (
"github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture"
"github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture/k8s"
rmFixture "github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture/rolloutmanager"
rolloutFixture "github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture/rollouts"

"sigs.k8s.io/controller-runtime/pkg/client"

Expand Down Expand Up @@ -136,6 +138,29 @@ var _ = Describe("Namespace-scoped RolloutManager tests", func() {
},
}, "3m", "2s").ShouldNot(k8s.ExistByName(k8sClient))

By("2nd RM: Delete 2nd Rollout CR and ensure it is not recreated.")
Expect(rolloutFixture.DeleteArgoRollout(ctx, utils.RolloutsName, nsName1)).To(Succeed())
Eventually(func() error {
_, err := rolloutFixture.GetArgoRollout(ctx, utils.RolloutsName, nsName1)
return err
}, "1m", "1s").ShouldNot(BeNil())

By("2nd RM: Create 3rd Rollout in 2nd namespace and ensure it is not reconciled, since RolloutsManager is deleted from 2nd namespace.")

_, err = rolloutFixture.CreateArgoRollout(ctx, "simple-rollout-1", nsName1, utils.RolloutsActiveServiceName, utils.RolloutsPreviewServiceName)
Expect(err).ToNot(HaveOccurred())
Consistently(func() bool {

res, err := rolloutFixture.HasEmptyStatus(ctx, "simple-rollout-1", nsName1)
if err != nil {
fmt.Println(err)
return false
}
return res

}, "1m", "1s").Should(
BeTrue(),
)
})

/*
Expand Down Expand Up @@ -177,6 +202,22 @@ var _ = Describe("Namespace-scoped RolloutManager tests", func() {
Expect(err).ToNot(HaveOccurred())
Eventually(&rolloutServicePreview, "10s", "1s").Should(k8s.ExistByName(k8sClient))

By("2nd NS: Create Argo Rollout CR in a 2nd namespace and verify that it is not reconciled by Rollouts controller of 1st namespace.")

_, err = rolloutFixture.CreateArgoRollout(ctx, utils.RolloutsName, nsName2, rolloutServiceActive.Name, rolloutServicePreview.Name)
Expect(err).ToNot(HaveOccurred())

Consistently(func() bool {

res, err := rolloutFixture.HasEmptyStatus(ctx, utils.RolloutsName, nsName1)
if err != nil {
return false
}
return res

}, "1m", "1s").Should(
BeTrue(),
)
})

/*
Expand Down Expand Up @@ -247,6 +288,21 @@ var _ = Describe("Namespace-scoped RolloutManager tests", func() {
rolloutServicePreview, err := utils.CreateService(ctx, k8sClient, utils.RolloutsPreviewServiceName, nsName, 32002)
Expect(err).ToNot(HaveOccurred())
Eventually(&rolloutServicePreview, "10s", "1s").Should(k8s.ExistByName(k8sClient))

By("2nd RM: Create Argo Rollout CR in 2nd namespace and verify that it is not reconciled.")

_, err = rolloutFixture.CreateArgoRollout(ctx, "simple-rollout-1", nsName, rolloutServiceActive.Name, rolloutServicePreview.Name)
Expect(err).ToNot(HaveOccurred())
Consistently(func() bool {
res, err := rolloutFixture.HasEmptyStatus(ctx, "simple-rollout-1", nsName)
if err != nil {
return false
}
return res

}, "30s", "1s").Should(
BeTrue(),
)
})
})
})
18 changes: 18 additions & 0 deletions tests/e2e/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture"
"github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture/k8s"

rolloutFixture "github.com/argoproj-labs/argo-rollouts-manager/tests/e2e/fixture/rollouts"

"sigs.k8s.io/controller-runtime/pkg/client"

rmv1alpha1 "github.com/argoproj-labs/argo-rollouts-manager/api/v1alpha1"
Expand Down Expand Up @@ -128,6 +130,22 @@ func ValidateArgoRolloutsResources(ctx context.Context, k8sClient client.Client,
Expect(err).ToNot(HaveOccurred())
Eventually(&rolloutServicePreview, "10s", "1s").Should(k8s.ExistByName(k8sClient))

By("Create Argo Rollout CR in given namespace and check it is reconciled successfully.")

_, err = rolloutFixture.CreateArgoRollout(ctx, RolloutsName, nsName, rolloutServiceActive.Name, rolloutServicePreview.Name)
Expect(err).ToNot(HaveOccurred())

Eventually(func() bool {

hasPhase, err := rolloutFixture.HasStatusPhase(ctx, RolloutsName, nsName, "Healthy")
if err != nil {
fmt.Println(err)
return false
}
return hasPhase

}, "3m", "1s").Should(BeTrue())

}

func validateServiceAccount(k8sClient client.Client, rolloutsManager rmv1alpha1.RolloutManager) {
Expand Down

0 comments on commit 905ece0

Please sign in to comment.