Skip to content

Commit

Permalink
change logic to check prefix of image url
Browse files Browse the repository at this point in the history
add install instructions

add in unit tests

Signed-off-by: craig <[email protected]>

rh-pre-commit.version: 2.2.0
rh-pre-commit.check-secrets: ENABLED
  • Loading branch information
maleck13 committed Dec 17, 2024
1 parent 6195492 commit 116d618
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 5 deletions.
5 changes: 5 additions & 0 deletions controllers/data_plane_policies_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ const (

var (
WASMFilterImageURL = env.GetString("RELATED_IMAGE_WASMSHIM", "oci://quay.io/kuadrant/wasm-shim:latest")
// protectedRegistry this defines a default protected registry. If this is in the wasm image URL we add a pull secret name to the WASMPLugin resource
ProtectedRegistry = env.GetString("PROTECTED_REGISTRY", "registry.redhat.com")

// registryPullSecretName this is the pull secret name we will add to the WASMPlugin if the URL for he image is from the defined PROTECTED_REGISTRY
RegistryPullSecretName = "wasm-plugin-pull-secret"

StateIstioExtensionsModified = "IstioExtensionsModified"
StateEnvoyGatewayExtensionsModified = "EnvoyGatewayExtensionsModified"
Expand Down
14 changes: 11 additions & 3 deletions controllers/envoy_gateway_extension_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"sync"

envoygatewayv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1"
Expand All @@ -15,7 +16,9 @@ import (
k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/dynamic"
"k8s.io/utils/ptr"
v1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"

kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1"
kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1"
Expand Down Expand Up @@ -76,8 +79,7 @@ func (r *EnvoyGatewayExtensionReconciler) Reconcile(ctx context.Context, _ []con

for _, gateway := range gateways {
gatewayKey := k8stypes.NamespacedName{Name: gateway.GetName(), Namespace: gateway.GetNamespace()}

desiredEnvoyExtensionPolicy := buildEnvoyExtensionPolicyForGateway(gateway, wasmConfigs[gateway.GetLocator()])
desiredEnvoyExtensionPolicy := buildEnvoyExtensionPolicyForGateway(gateway, wasmConfigs[gateway.GetLocator()], ProtectedRegistry)

Check warning on line 82 in controllers/envoy_gateway_extension_reconciler.go

View check run for this annotation

Codecov / codecov/patch

controllers/envoy_gateway_extension_reconciler.go#L82

Added line #L82 was not covered by tests

resource := r.client.Resource(kuadrantenvoygateway.EnvoyExtensionPoliciesResource).Namespace(desiredEnvoyExtensionPolicy.GetNamespace())

Expand Down Expand Up @@ -216,7 +218,7 @@ func (r *EnvoyGatewayExtensionReconciler) buildWasmConfigs(ctx context.Context,
}

// buildEnvoyExtensionPolicyForGateway builds a desired EnvoyExtensionPolicy custom resource for a given gateway and corresponding wasm config
func buildEnvoyExtensionPolicyForGateway(gateway *machinery.Gateway, wasmConfig wasm.Config) *envoygatewayv1alpha1.EnvoyExtensionPolicy {
func buildEnvoyExtensionPolicyForGateway(gateway *machinery.Gateway, wasmConfig wasm.Config, protectedRegistry string) *envoygatewayv1alpha1.EnvoyExtensionPolicy {
envoyPolicy := &envoygatewayv1alpha1.EnvoyExtensionPolicy{
TypeMeta: metav1.TypeMeta{
Kind: kuadrantenvoygateway.EnvoyExtensionPolicyGroupKind.Kind,
Expand Down Expand Up @@ -269,6 +271,12 @@ func buildEnvoyExtensionPolicyForGateway(gateway *machinery.Gateway, wasmConfig
},
}

if protectedRegistry != "" && strings.Contains(WASMFilterImageURL, protectedRegistry) {
for _, wasm := range envoyPolicy.Spec.Wasm {
wasm.Code.Image.PullSecretRef = &gwapiv1b1.SecretObjectReference{Name: v1.ObjectName(RegistryPullSecretName)}
}
}

if len(wasmConfig.ActionSets) == 0 {
utils.TagObjectToDelete(envoyPolicy)
} else {
Expand Down
136 changes: 136 additions & 0 deletions controllers/extenstion_reconciler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//go:build unit

package controllers

import (
"fmt"
"testing"

envoygatewayv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/kuadrant/kuadrant-operator/pkg/wasm"
"github.com/kuadrant/policy-machinery/machinery"
istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "sigs.k8s.io/gateway-api/apis/v1"
)

var (
defaultWasmImage = WASMFilterImageURL
registry = "protected.registry.io"
protectedRegImage = fmt.Sprintf("oci://%s/kuadrant/wasm-shim:latest", registry)
testGateway = &machinery.Gateway{
Gateway: &v1.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test",
},
},
}
testWasmConfig = wasm.Config{
ActionSets: []wasm.ActionSet{
{
Name: "test",
},
},
}
)

func Test_buildIstioWasmPluginForGateway(t *testing.T) {
testCases := []struct {
Name string
setWASMImageURL func()
ProtectedRegistryPrefix string
Assert func(t *testing.T, plugin *istioclientgoextensionv1alpha1.WasmPlugin)
}{
{
Name: "ensure image pull secret is set in wasmPlugin for protected registry",
setWASMImageURL: func() {
WASMFilterImageURL = protectedRegImage
},
ProtectedRegistryPrefix: registry,
Assert: func(t *testing.T, plugin *istioclientgoextensionv1alpha1.WasmPlugin) {
if plugin == nil {
t.Fatalf("Expected a wasmplugin")
}
if plugin.Spec.ImagePullSecret != RegistryPullSecretName {
t.Fatalf("Expected wasm plugin to have imagePullSecret %s but got %s", RegistryPullSecretName, plugin.Spec.ImagePullSecret)
}
},
},
{
Name: "ensure image pull secret is NOT set in wasmPlugin for unprotected registry",
setWASMImageURL: func() {
WASMFilterImageURL = defaultWasmImage
},
Assert: func(t *testing.T, plugin *istioclientgoextensionv1alpha1.WasmPlugin) {
if plugin == nil {
t.Fatalf("Expected a wasmplugin")
}
if plugin.Spec.ImagePullSecret != "" {
t.Fatalf("Expected wasm plugin to have not imagePullSecret %s", plugin.Spec.ImagePullSecret)
}
},
},
}

for _, testCase := range testCases {
t.Run(testCase.Name, func(t *testing.T) {
testCase.setWASMImageURL()
plugin := buildIstioWasmPluginForGateway(testGateway, testWasmConfig, testCase.ProtectedRegistryPrefix)
testCase.Assert(t, plugin)
})
}

}

func Test_buildEnvoyExtensionPolicyForGateway(t *testing.T) {
testCases := []struct {
Name string
setWASMImageURL func()
ProtectedRegistryPrefix string
Assert func(t *testing.T, policy *envoygatewayv1alpha1.EnvoyExtensionPolicy)
}{
{
Name: "ensure image pull secret is set in ExtensionPolicy for protected registry",
setWASMImageURL: func() {
WASMFilterImageURL = protectedRegImage
},
ProtectedRegistryPrefix: registry,
Assert: func(t *testing.T, policy *envoygatewayv1alpha1.EnvoyExtensionPolicy) {
if policy == nil {
t.Fatalf("Expected a wasmplugin")
}
for _, w := range policy.Spec.Wasm {
if w.Code.Image.PullSecretRef == nil {
t.Fatalf("Expected extension to have imagePullSecret %s but no pullSecretRef", RegistryPullSecretName)
}
if w.Code.Image.PullSecretRef.Name != v1.ObjectName(RegistryPullSecretName) {
t.Fatalf("expected the pull secret name to be %s but got %v", RegistryPullSecretName, w.Code.Image.PullSecretRef.Name)
}
}
},
},
{
Name: "ensure image pull secret is NOT set in wasmPlugin for unprotected registry",
setWASMImageURL: func() {
WASMFilterImageURL = defaultWasmImage
},
Assert: func(t *testing.T, policy *envoygatewayv1alpha1.EnvoyExtensionPolicy) {
if policy == nil {
t.Fatalf("Expected a wasmplugin")
}
for _, w := range policy.Spec.Wasm {
if w.Code.Image.PullSecretRef != nil {
t.Fatalf("Expected extension to have not imagePullSecret but got %v", w.Code.Image.PullSecretRef)
}
}
},
},
}

for _, testCase := range testCases {
testCase.setWASMImageURL()
policy := buildEnvoyExtensionPolicyForGateway(testGateway, testWasmConfig, testCase.ProtectedRegistryPrefix)
testCase.Assert(t, policy)
}
}
9 changes: 7 additions & 2 deletions controllers/istio_extension_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"sync"

"github.com/kuadrant/policy-machinery/controller"
Expand Down Expand Up @@ -78,7 +79,7 @@ func (r *IstioExtensionReconciler) Reconcile(ctx context.Context, _ []controller
for _, gateway := range gateways {
gatewayKey := k8stypes.NamespacedName{Name: gateway.GetName(), Namespace: gateway.GetNamespace()}

desiredWasmPlugin := buildIstioWasmPluginForGateway(gateway, wasmConfigs[gateway.GetLocator()])
desiredWasmPlugin := buildIstioWasmPluginForGateway(gateway, wasmConfigs[gateway.GetLocator()], ProtectedRegistry)

Check warning on line 82 in controllers/istio_extension_reconciler.go

View check run for this annotation

Codecov / codecov/patch

controllers/istio_extension_reconciler.go#L82

Added line #L82 was not covered by tests

resource := r.client.Resource(kuadrantistio.WasmPluginsResource).Namespace(desiredWasmPlugin.GetNamespace())

Expand Down Expand Up @@ -228,7 +229,7 @@ func hasAuthAccess(actionSet []wasm.Action) bool {
}

// buildIstioWasmPluginForGateway builds a desired WasmPlugin custom resource for a given gateway and corresponding wasm config
func buildIstioWasmPluginForGateway(gateway *machinery.Gateway, wasmConfig wasm.Config) *istioclientgoextensionv1alpha1.WasmPlugin {
func buildIstioWasmPluginForGateway(gateway *machinery.Gateway, wasmConfig wasm.Config, protectedRegistry string) *istioclientgoextensionv1alpha1.WasmPlugin {
wasmPlugin := &istioclientgoextensionv1alpha1.WasmPlugin{
TypeMeta: metav1.TypeMeta{
Kind: kuadrantistio.WasmPluginGroupKind.Kind,
Expand Down Expand Up @@ -263,6 +264,10 @@ func buildIstioWasmPluginForGateway(gateway *machinery.Gateway, wasmConfig wasm.
},
}

if protectedRegistry != "" && strings.Contains(WASMFilterImageURL, protectedRegistry) {
wasmPlugin.Spec.ImagePullSecret = RegistryPullSecretName
}

if len(wasmConfig.ActionSets) == 0 {
utils.TagObjectToDelete(wasmPlugin)
} else {
Expand Down
13 changes: 13 additions & 0 deletions doc/install/install-openshift.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,19 @@ spec:
upgradeStrategy: Default
EOF
```
**Authenticated Registry**

!!! note

If you need to use a wasm image from a protected registry (such as the redhat registry), you will need to configure an image pull secret to use. This secret must exist in each namespace where there is a Gateway resource defined that you intend to target with `AuthPolicy` or `RatelimitPolicy` and it must be named `wasm-plugin-pull-secret`.

Example Creating Pull Secret:

```bash
kubectl create secret docker-registry wasm-plugin-pull-secret -n ${GATEWAY_NAMESPACE} \ --docker-server=my.registry.io \ --docker-username=your-registry-service-account-username \ --docker-password=your-registry-service-account-password
```

The configuration for the gateway will expect this secret to exist if the registry name begins with `registry.redhat.com` by default. This can be changed via the env var `PROTECTED_REGISTRY` set in the kuadrant-operator.

Wait for the Kuadrant Operators to be installed as follows:

Expand Down
1 change: 1 addition & 0 deletions tests/istio/extension_reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() {
Expect(existingWasmPlugin.Spec.TargetRefs[0].Group).To(Equal("gateway.networking.k8s.io"))
Expect(existingWasmPlugin.Spec.TargetRefs[0].Kind).To(Equal("Gateway"))
Expect(existingWasmPlugin.Spec.TargetRefs[0].Name).To(Equal(gateway.Name))
Expect(existingWasmPlugin.Spec.ImagePullSecret).To(BeEmpty())
existingWASMConfig, err := wasm.ConfigFromStruct(existingWasmPlugin.Spec.PluginConfig)
Expect(err).ToNot(HaveOccurred())
Expect(existingWASMConfig).To(Equal(&wasm.Config{
Expand Down

0 comments on commit 116d618

Please sign in to comment.