Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: removes authconfig creation #85

Merged
merged 2 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ help: ## Display this help.
.PHONY: generate
generate: tools ## Generates required resources for the controller to work properly (see config/ folder)
$(LOCALBIN)/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(call fetch-external-crds,github.com/kuadrant/authorino,api/v1beta1)
$(call fetch-external-crds,github.com/openshift/api,route/v1)

SRC_DIRS:=./controllers ./test
Expand Down
142 changes: 0 additions & 142 deletions controllers/enable_authorino.go

This file was deleted.

31 changes: 2 additions & 29 deletions controllers/mesh_env_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@ package controllers

import (
"os"
"strings"

"github.com/pkg/errors"
)

const (
MeshNamespaceEnv = "MESH_NAMESPACE"
ControlPlaneEnv = "CONTROL_PLANE_NAME"
AuthorinoLabelSelector = "AUTHORINO_LABEL"
AuthAudience = "AUTH_AUDIENCE"
MeshNamespaceEnv = "MESH_NAMESPACE"
ControlPlaneEnv = "CONTROL_PLANE_NAME"
)

func getControlPlaneName() string {
Expand All @@ -22,28 +17,6 @@ func getMeshNamespace() string {
return getEnvOr(MeshNamespaceEnv, "istio-system")
}

func getAuthorinoLabel() ([]string, error) {
label := getEnvOr(AuthorinoLabelSelector, "authorino/topic=odh")
keyValue := strings.Split(label, "=")

if len(keyValue) != 2 {
return nil, errors.Errorf("Expected authorino label to be in key=value format, got [%s]", label)
}

return keyValue, nil
}

func getAuthAudience() []string {
aud := getEnvOr(AuthAudience, "https://kubernetes.default.svc")
audiences := strings.Split(aud, ",")

for i := range audiences {
audiences[i] = strings.TrimSpace(audiences[i])
}

return audiences
}

func getEnvOr(key, defaultValue string) string {
if env, defined := os.LookupEnv(key); defined {
return env
Expand Down
21 changes: 21 additions & 0 deletions controllers/namespace_updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package controllers
import (
"context"
"fmt"
"regexp"
"strings"

"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -50,3 +52,22 @@ func extractGateway(meta metav1.ObjectMeta) string {

return gateway
}

// ExtractHostName strips given URL in string from http(s):// prefix and subsequent path.
// This is useful when getting value from http headers (such as origin), as Authorino needs host only.
// If given string does not start with http(s) prefix it will be returned as is.
func ExtractHostName(s string) string {
r := regexp.MustCompile(`^(https?://)`)

withoutProtocol := r.ReplaceAllString(s, "")
if s == withoutProtocol {
return s
}

index := strings.Index(withoutProtocol, "/")
if index == -1 {
return withoutProtocol
}

return withoutProtocol[:index]
}
4 changes: 3 additions & 1 deletion controllers/project_mesh_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ type OpenshiftServiceMeshReconciler struct {
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch
// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch;create;update;patch

type reconcileFunc func(ctx context.Context, namespace *v1.Namespace) error

// Reconcile ensures that the namespace has all required resources needed to be part of the Service Mesh of Open Data Hub.
func (r *OpenshiftServiceMeshReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := r.Log.WithValues("name", req.Name, "namespace", req.Namespace)

reconcilers := []reconcileFunc{r.addGatewayAnnotations, r.reconcileMeshMember, r.reconcileAuthConfig}
reconcilers := []reconcileFunc{r.addGatewayAnnotations, r.reconcileMeshMember}

namespace := &v1.Namespace{}
if err := r.Get(ctx, req.NamespacedName, namespace); err != nil {
Expand Down
120 changes: 0 additions & 120 deletions controllers/project_mesh_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import (
"os"
"time"

authorino "github.com/kuadrant/authorino/api/v1beta1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/opendatahub-io/odh-project-controller/controllers"
"github.com/opendatahub-io/odh-project-controller/test"
. "github.com/opendatahub-io/odh-project-controller/test/cluster"
"github.com/opendatahub-io/odh-project-controller/test/labels"
openshiftv1 "github.com/openshift/api/route/v1"
Expand Down Expand Up @@ -203,124 +201,6 @@ var _ = When("Namespace is created", Label(labels.EnvTest), func() {
})
})

Context("enabling external authorization", func() {

It("should configure authorization using defaults for ns belonging to the mesh", func() {
// given
testNs = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "meshified-and-authorized-ns",
Annotations: map[string]string{
controllers.AnnotationServiceMesh: "true",
},
},
}

defer objectCleaner.DeleteAll(testNs)

// when
Expect(cli.Create(context.Background(), testNs)).To(Succeed())

// then
By("creating authorization config resource", func() {
expectedAuthConfig := &authorino.AuthConfig{}

Expect(controllers.ConvertToStructuredResource(test.ExpectedAuthConfig, expectedAuthConfig)).To(Succeed())
namespacedName := types.NamespacedName{
Namespace: testNs.Name,
Name: expectedAuthConfig.Name,
}
actualAuthConfig := &authorino.AuthConfig{}
Eventually(func() error {
return cli.Get(context.Background(), namespacedName, actualAuthConfig)
}).
WithTimeout(timeout).
WithPolling(interval).
Should(Succeed())

Expect(actualAuthConfig.Labels).To(Equal(expectedAuthConfig.Labels))
Expect(actualAuthConfig.Name).To(Equal(testNs.GetName() + "-protection"))
Expect(actualAuthConfig.Spec.Hosts).To(Equal(expectedAuthConfig.Spec.Hosts))
})
})

It("should configure authorization using env vars for ns belonging to the mesh", func() {
// given
testNs = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "meshified-and-authorized-ns",
Annotations: map[string]string{
controllers.AnnotationServiceMesh: "true",
},
},
}

defer objectCleaner.DeleteAll(testNs)

// when
_ = os.Setenv(controllers.AuthorinoLabelSelector, "app=rhods")
defer os.Unsetenv(controllers.AuthorinoLabelSelector)
_ = os.Setenv(controllers.AuthAudience, "opendatahub.io,foo , bar")
defer os.Unsetenv(controllers.AuthAudience)

Expect(cli.Create(context.Background(), testNs)).To(Succeed())

// then
By("creating authorization config resource", func() {
expectedAuthConfig := &authorino.AuthConfig{}

Expect(controllers.ConvertToStructuredResource(test.ExpectedAuthConfig, expectedAuthConfig)).To(Succeed())
namespacedName := types.NamespacedName{
Namespace: testNs.Name,
Name: expectedAuthConfig.Name,
}
actualAuthConfig := &authorino.AuthConfig{}
Eventually(func() error {
return cli.Get(context.Background(), namespacedName, actualAuthConfig)
}).
WithTimeout(timeout).
WithPolling(interval).
Should(Succeed())

Expect(actualAuthConfig.Name).To(Equal(testNs.GetName() + "-protection"))
Expect(actualAuthConfig.Labels).To(HaveKeyWithValue("app", "rhods"))
Expect(actualAuthConfig.Spec.Hosts).To(Equal(expectedAuthConfig.Spec.Hosts))
Expect(actualAuthConfig.Spec.Identity[0].KubernetesAuth.Audiences).
To(And(HaveLen(3), ContainElements("opendatahub.io", "foo", "bar")))
})
})

It("should not configure authorization rules if namespace is not part of the mesh", func() {
// given
testNs = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "not-meshified-nor-authorized-namespace",
},
}

// when
Expect(cli.Create(context.Background(), testNs)).To(Succeed())

// then
By("ensuring no authorization config has been created", func() {
authConfigs := &authorino.AuthConfigList{}

Consistently(func() bool {
if err := cli.List(context.Background(), authConfigs, client.InNamespace(testNs.Name)); err != nil {
fmt.Printf("failed ensuring no auth config created: %+v\n", err)

return false
}

return len(authConfigs.Items) == 0
}).
WithTimeout(timeout).
WithPolling(interval).
Should(BeTrue())
})
})
})

Context("propagating service mesh gateway info", func() {

It("should add just gateway name to the namespace if there is no gateway namespace defined", func() {
Expand Down
Loading
Loading