Skip to content

Commit

Permalink
namespace to conversion (#570)
Browse files Browse the repository at this point in the history
* namespace to conversion

Signed-off-by: Cameron Wall <[email protected]>

* unit test

Signed-off-by: Cameron Wall <[email protected]>

* code quality

Signed-off-by: Cameron Wall <[email protected]>

* code quality

Signed-off-by: Cameron Wall <[email protected]>

---------

Signed-off-by: Cameron Wall <[email protected]>
  • Loading branch information
cameronmwall authored Feb 5, 2024
1 parent c12037c commit 262ce07
Show file tree
Hide file tree
Showing 7 changed files with 721 additions and 7 deletions.
59 changes: 59 additions & 0 deletions controllers/backplaneconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/stolostron/backplane-operator/pkg/status"
"github.com/stolostron/backplane-operator/pkg/utils"
"github.com/stolostron/backplane-operator/pkg/version"
"k8s.io/client-go/util/retry"
clustermanager "open-cluster-management.io/api/operator/v1"

configv1 "github.com/openshift/api/config/v1"
Expand Down Expand Up @@ -319,6 +320,38 @@ func (r *MultiClusterEngineReconciler) Reconcile(ctx context.Context, req ctrl.R
defer r.ScheduleOperatorControllerResync(ctx, req)
}

var crdsDir string

if val, ok := os.LookupEnv("UNIT_TEST"); ok && val == "true" {
crdsDir = "test/unit-test-crds"
} else {

crdsDir = " pkg/templates/crds"
}
crds, errs := renderer.RenderCRDs(crdsDir, backplaneConfig)
if len(errs) > 0 {
for _, err := range errs {

return result, err
}
}

// udpate CRDs with retrygo
for i := range crds {
_, conversion, _ := unstructured.NestedMap(crds[i].Object, "spec", "conversion", "webhook", "clientConfig", "service")
if conversion {
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
crd := crds[i]
e := ensureCRD(context.TODO(), r.Client, crd)
return e
})
if retryErr != nil {
log.Error(retryErr, "Failed to apply CRD")
return result, retryErr
}
}
}

result, err = r.DeployAlwaysSubcomponents(ctx, backplaneConfig)
if err != nil {
cond := status.NewCondition(
Expand Down Expand Up @@ -1462,3 +1495,29 @@ func (r *MultiClusterEngineReconciler) StopScheduleOperatorControllerResync() {
r.InitScheduler()
}
}

func ensureCRD(ctx context.Context, c client.Client, crd *unstructured.Unstructured) error {
existingCRD := &unstructured.Unstructured{}
existingCRD.SetGroupVersionKind(crd.GroupVersionKind())
err := c.Get(ctx, types.NamespacedName{Name: crd.GetName()}, existingCRD)
if err != nil && apierrors.IsNotFound(err) {
// CRD not found. Create and return
err = c.Create(ctx, crd)
if err != nil {
return fmt.Errorf("error creating CRD '%s': %w", crd.GetName(), err)
}
} else if err != nil {
return fmt.Errorf("error getting CRD '%s': %w", crd.GetName(), err)
} else if err == nil {
// CRD already exists. Update and return
if utils.AnnotationPresent(utils.AnnotationMCEIgnore, existingCRD) {
return nil
}
crd.SetResourceVersion(existingCRD.GetResourceVersion())
err = c.Update(ctx, crd)
if err != nil {
return fmt.Errorf("error updating CRD '%s': %w", crd.GetName(), err)
}
}
return nil
}
2 changes: 1 addition & 1 deletion controllers/hosted.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func (r *MultiClusterEngineReconciler) HostedReconcile(ctx context.Context, mce

// Render CRD templates
crdsDir := "pkg/templates/hosted-crds"
crds, errs := renderer.RenderCRDs(crdsDir)
crds, errs := renderer.RenderCRDs(crdsDir, mce)
for _, err := range errs {
log.Info(err.Error())
}
Expand Down
4 changes: 2 additions & 2 deletions controllers/toggle_components.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (r *MultiClusterEngineReconciler) ensureManagedServiceAccount(ctx context.C

// Render CRD templates
crdPath := toggle.ManagedServiceAccountCRDPath
crds, errs := renderer.RenderCRDs(crdPath)
crds, errs := renderer.RenderCRDs(crdPath, backplaneConfig)
if len(errs) > 0 {
for _, err := range errs {
log.Info(err.Error())
Expand Down Expand Up @@ -212,7 +212,7 @@ func (r *MultiClusterEngineReconciler) ensureNoManagedServiceAccount(ctx context

// Render CRD templates
crdPath := toggle.ManagedServiceAccountCRDPath
crds, errs := renderer.RenderCRDs(crdPath)
crds, errs := renderer.RenderCRDs(crdPath, backplaneConfig)
if len(errs) > 0 {
for _, err := range errs {
log.Info(err.Error())
Expand Down
4 changes: 3 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ func main() {

// Render CRD templates
crdsDir := crdsDir
crds, errs := renderer.RenderCRDs(crdsDir)

var backplaneConfig *backplanev1.MultiClusterEngine
crds, errs := renderer.RenderCRDs(crdsDir, backplaneConfig)
if len(errs) > 0 {
for _, err := range errs {
setupLog.Info(err.Error())
Expand Down
8 changes: 7 additions & 1 deletion pkg/rendering/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (val *Values) ToValues() (chartutil.Values, error) {
return vals, nil
}

func RenderCRDs(crdDir string) ([]*unstructured.Unstructured, []error) {
func RenderCRDs(crdDir string, backplaneConfig *v1.MultiClusterEngine) ([]*unstructured.Unstructured, []error) {
var crds []*unstructured.Unstructured
errs := []error{}

Expand All @@ -171,6 +171,12 @@ func RenderCRDs(crdDir string) ([]*unstructured.Unstructured, []error) {
if err = yaml.Unmarshal(bytesFile, crd); err != nil {
errs = append(errs, fmt.Errorf("%s - error unmarshalling file to unstructured: %v", info.Name(), err.Error()))
}
if backplaneConfig != nil {
_, conversion, _ := unstructured.NestedMap(crd.Object, "spec", "conversion", "webhook", "clientConfig", "service")
if conversion {
crd.Object["spec"].(map[string]interface{})["conversion"].(map[string]interface{})["webhook"].(map[string]interface{})["clientConfig"].(map[string]interface{})["service"].(map[string]interface{})["namespace"] = backplaneConfig.Spec.TargetNamespace
}
}
crds = append(crds, crd)
return nil
})
Expand Down
53 changes: 51 additions & 2 deletions pkg/rendering/renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
)

const (
chartsDir = "pkg/templates/charts/toggle"
chartsPath = "pkg/templates/charts/toggle/managed-serviceaccount"
crdsDir = "pkg/templates/crds"
crdsDir = "../../hack/unit-test-crds"
)

func TestRender(t *testing.T) {
Expand Down Expand Up @@ -272,7 +273,49 @@ func TestRender(t *testing.T) {

}

func TestRenderCoreCRDs(t *testing.T) {
tests := []struct {
name string
crdDir string
want []error
}{
{
name: "Render CRDs directory",
crdDir: crdsDir,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var backplaneConfig *backplane.MultiClusterEngine
got, errs := RenderCRDs(tt.crdDir, backplaneConfig)
if errs != nil && len(errs) > 1 {
t.Errorf("RenderCRDs() got = %v, want %v", errs, nil)
}

for _, u := range got {
kind := "CustomResourceDefinition"
apiVersion := "apiextensions.k8s.io/v1"
if u.GetKind() != kind {
t.Errorf("RenderCRDs() got Kind = %v, want Kind %v", errs, kind)
}

if u.GetAPIVersion() != apiVersion {
t.Errorf("RenderCRDs() got apiversion = %v, want apiversion %v", errs, apiVersion)
}
}
})
}
}
func TestRenderCRDs(t *testing.T) {
testBackplane := &backplane.MultiClusterEngine{
ObjectMeta: metav1.ObjectMeta{
Name: "testBackplane",
},
Spec: backplane.MultiClusterEngineSpec{},
Status: backplane.MultiClusterEngineStatus{
Phase: "",
},
}
tests := []struct {
name string
crdDir string
Expand All @@ -285,7 +328,7 @@ func TestRenderCRDs(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, errs := RenderCRDs(tt.crdDir)
got, errs := RenderCRDs(tt.crdDir, testBackplane)
if errs != nil && len(errs) > 1 {
t.Errorf("RenderCRDs() got = %v, want %v", errs, nil)
}
Expand All @@ -300,6 +343,12 @@ func TestRenderCRDs(t *testing.T) {
if u.GetAPIVersion() != apiVersion {
t.Errorf("RenderCRDs() got apiversion = %v, want apiversion %v", errs, apiVersion)
}

namespace, conversion, _ := unstructured.NestedString(u.Object, "spec", "conversion", "webhook", "clientConfig", "service", "namespace")
if conversion && namespace != "" {
t.Errorf("did not properly set namespace")
}

}
})
}
Expand Down
Loading

0 comments on commit 262ce07

Please sign in to comment.