Skip to content

Commit

Permalink
Add support for project sail (#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-cattermole authored Dec 8, 2023
1 parent d1b8ddd commit 6e985e3
Show file tree
Hide file tree
Showing 22 changed files with 728 additions and 220 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ jobs:

integration-tests:
name: Integration Tests
strategy:
matrix:
istio-type: [ sail, istioctl ]
runs-on: ubuntu-latest
env:
KIND_CLUSTER_NAME: kuadrant-test
Expand Down Expand Up @@ -73,9 +76,9 @@ jobs:
- name: Check cluster info
run: |
kubectl cluster-info dump
- name: Run make test-env-setup
- name: Run make test-env-setup istio-type=${{ matrix.istio-type }}
run: |
make test-env-setup
make test-env-setup ISTIO_INSTALL_SAIL=${{ matrix.istio-type == 'sail' && true || false }}
- name: Wait for deployments
run: |
kubectl -n ${{ env.KUADRANT_NAMESPACE }} wait --timeout=300s --for=condition=Available deployments --all
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ local-deploy: ## Deploy Kuadrant Operator in the cluster pointed by KUBECONFIG
kubectl -n $(KUADRANT_NAMESPACE) wait --timeout=300s --for=condition=Available deployments --all
@echo
@echo "Now you can export the kuadrant gateway by doing:"
@echo "kubectl port-forward -n istio-system service/istio-ingressgateway 9080:80 &"
@echo "kubectl port-forward -n istio-system service/istio-ingressgateway-istio 9080:80 &"
@echo "after that, you can curl -H \"Host: myhost.com\" localhost:9080"
@echo "-- Linux only -- Ingress gateway is exported using nodePort service in port 9080"
@echo "curl -H \"Host: myhost.com\" localhost:9080"
Expand Down Expand Up @@ -378,6 +378,7 @@ undeploy-policy-controller: ## Undeploy policy-controller from the K8s cluster s
.PHONY: install-metallb
install-metallb: $(KUSTOMIZE) ## Installs the metallb load balancer allowing use of an LoadBalancer type with a gateway
$(KUSTOMIZE) build config/metallb | kubectl apply -f -
kubectl -n metallb-system wait --for=condition=Available deployments controller --timeout=300s
kubectl -n metallb-system wait --for=condition=ready pod --selector=app=metallb --timeout=60s
./utils/docker-network-ipaddresspool.sh kind | kubectl apply -n metallb-system -f -

Expand Down
11 changes: 11 additions & 0 deletions bundle/manifests/kuadrant-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,17 @@ spec:
- patch
- update
- watch
- apiGroups:
- operator.istio.io
resources:
- istios
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- security.istio.io
resources:
Expand Down
5 changes: 1 addition & 4 deletions config/dependencies/gateway-api/gateway/gateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ metadata:
spec:
gatewayClassName: istio
listeners:
- name: default
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
addresses:
- value: istio-ingressgateway.istio-system.svc.cluster.local
type: Hostname
15 changes: 15 additions & 0 deletions config/dependencies/istio/sail/istio.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: operator.istio.io/v1alpha1
kind: Istio
metadata:
name: istiocontrolplane
namespace: istio-system
spec:
version: v1.20.0
# Disable autoscaling to reduce dev resources
values:
pilot:
autoscaleEnabled: false
rawValues:
gateways:
istio-ingressgateway:
autoscaleEnabled: false
4 changes: 4 additions & 0 deletions config/dependencies/istio/sail/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
namespace: istio-system
resources:
- github.com/maistra/istio-operator/config/default?ref=maistra-3.0
11 changes: 11 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,17 @@ rules:
- patch
- update
- watch
- apiGroups:
- operator.istio.io
resources:
- istios
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- security.istio.io
resources:
Expand Down
35 changes: 23 additions & 12 deletions controllers/kuadrant_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
istiov1alpha1 "maistra.io/istio-operator/api/v1alpha1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
Expand Down Expand Up @@ -70,6 +71,7 @@ type KuadrantReconciler struct {
//+kubebuilder:rbac:groups="gateway.networking.k8s.io",resources=httproutes,verbs=get;list;patch;update;watch
//+kubebuilder:rbac:groups=operator.authorino.kuadrant.io,resources=authorinos,verbs=get;list;watch;create;update;delete;patch
//+kubebuilder:rbac:groups=install.istio.io,resources=istiooperators,verbs=get;list;watch;create;update;patch
//+kubebuilder:rbac:groups=operator.istio.io,resources=istios,verbs=get;list;watch;create;update;patch
//+kubebuilder:rbac:groups=maistra.io,resources=servicemeshcontrolplanes,verbs=get;list;watch;update;use;patch
//+kubebuilder:rbac:groups=maistra.io,resources=servicemeshmembers,verbs=get;list;watch;create;update;delete;patch

Expand Down Expand Up @@ -320,23 +322,32 @@ func (r *KuadrantReconciler) getIstioConfigObjects(ctx context.Context, logger l
var configsToUpdate []common.ConfigWrapper

iop := &iopv1alpha1.IstioOperator{}
iopKey := client.ObjectKey{Name: controlPlaneProviderName(), Namespace: controlPlaneProviderNamespace()}
if err := r.GetResource(ctx, iopKey, iop); err != nil {
logger.V(1).Info("failed to get istiooperator object", "key", iopKey, "err", err)
if apimeta.IsNoMatchError(err) {
// return nil and nil if there's no istiooperator CRD, means istio is not installed
return nil, nil
} else if !apierrors.IsNotFound(err) {
// return nil and err if there's an error other than not found (no istiooperator CR)
return nil, err
}
} else {
istKey := client.ObjectKey{Name: controlPlaneProviderName(), Namespace: controlPlaneProviderNamespace()}
err := r.GetResource(ctx, istKey, iop)
if err == nil || apierrors.IsNotFound(err) {
configsToUpdate = append(configsToUpdate, istio.NewOperatorWrapper(iop))
} else if !apimeta.IsNoMatchError(err) {
logger.V(1).Info("failed to get istiooperator object", "key", istKey, "err", err)
return nil, err
} else {
// Error is NoMatchError so check for Istio CR instead
ist := &istiov1alpha1.Istio{}
if err := r.GetResource(ctx, istKey, ist); err != nil {
logger.V(1).Info("failed to get istio object", "key", istKey, "err", err)
if apimeta.IsNoMatchError(err) {
// return nil and nil if there's no istiooperator or istio CR
return nil, nil
} else if !apierrors.IsNotFound(err) {
// return nil and err if there's an error other than not found (no istio CR)
return nil, err
}
}
configsToUpdate = append(configsToUpdate, istio.NewSailWrapper(ist))
}

istioConfigMap := &corev1.ConfigMap{}
if err := r.GetResource(ctx, client.ObjectKey{Name: controlPlaneConfigMapName(), Namespace: controlPlaneProviderNamespace()}, istioConfigMap); err != nil {
logger.V(1).Info("failed to get istio configMap", "key", iopKey, "err", err)
logger.V(1).Info("failed to get istio configMap", "key", istKey, "err", err)
return configsToUpdate, err
}
configsToUpdate = append(configsToUpdate, istio.NewConfigMapWrapper(istioConfigMap))
Expand Down
4 changes: 4 additions & 0 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
istioapis "istio.io/istio/operator/pkg/apis"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
istiov1alpha1 "maistra.io/istio-operator/api/v1alpha1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
Expand Down Expand Up @@ -95,6 +96,9 @@ var _ = BeforeSuite(func() {
err = istioapis.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

err = istiov1alpha1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

err = istiosecurityv1beta1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

Expand Down
24 changes: 16 additions & 8 deletions doc/user-guides/auth-for-app-devs-and-platform-engineers.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,28 @@ spec:
EOF
```

Export the gateway hostname and port:

```sh
export INGRESS_HOST=$(kubectl get gtw istio-ingressgateway -n istio-system -o jsonpath='{.status.addresses[0].value}')
export INGRESS_PORT=$(kubectl get gtw istio-ingressgateway -n istio-system -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
```

Send requests to the application unprotected:

```sh
curl -H 'Host: api.toystore.com' http://localhost:9080/cars -i
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/cars -i
# HTTP/1.1 200 OK
```

```sh
curl -H 'Host: api.toystore.com' http://localhost:9080/dolls -i
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/dolls -i
# HTTP/1.1 200 OK
```

```sh
curl -H 'Host: api.toystore.com' http://localhost:9080/admin -i
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/admin -i
# HTTP/1.1 200 OK
```

Expand Down Expand Up @@ -199,22 +207,22 @@ EOF
Send requests to the application protected by Kuadrant:

```sh
curl -H 'Host: api.toystore.com' http://localhost:9080/cars -i
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/cars -i
# HTTP/1.1 401 Unauthorized
```

```sh
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://localhost:9080/cars -i
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://$GATEWAY_URL/cars -i
# HTTP/1.1 200 OK
```

```sh
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://localhost:9080/admin -i
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamaregularuser' http://$GATEWAY_URL/admin -i
# HTTP/1.1 403 Forbidden
```

```sh
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamanadmin' http://localhost:9080/admin -i
curl -H 'Host: api.toystore.com' -H 'Authorization: APIKEY iamanadmin' http://$GATEWAY_URL/admin -i
# HTTP/1.1 200 OK
```

Expand Down Expand Up @@ -274,7 +282,7 @@ EOF
Send requests to the route protected by the default policy set at the level of the gateway:

```sh
curl -H 'Host: foo.other-apps.com' http://localhost:9080/ -i
curl -H 'Host: foo.other-apps.com' http://$GATEWAY_URL/ -i
# HTTP/1.1 403 Forbidden
```

Expand Down
20 changes: 15 additions & 5 deletions doc/user-guides/authenticated-rl-for-app-developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,27 @@ spec:
EOF
```

Export the gateway hostname and port:

```sh
export INGRESS_HOST=$(kubectl get gtw istio-ingressgateway -n istio-system -o jsonpath='{.status.addresses[0].value}')
export INGRESS_PORT=$(kubectl get gtw istio-ingressgateway -n istio-system -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
```

Verify the route works:

```sh
curl -H 'Host: api.toystore.com' http://localhost:9080/toy -i
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy -i
# HTTP/1.1 200 OK
```

> **Note**: If the command above fails to hit the Toy Store API on your environment, try forwarding requests to the service:
> **Note**: If the command above fails to hit the Toy Store API on your environment, try forwarding requests to the service and accessing over localhost:
>
> ```sh
> kubectl port-forward -n istio-system service/istio-ingressgateway 9080:80 2>&1 >/dev/null &
> curl -H 'Host: api.toystore.com' http://localhost:9080/toy -i
> # HTTP/1.1 200 OK
> ```

### ③ Enforce authentication on requests to the Toy Store API
Expand Down Expand Up @@ -139,7 +149,7 @@ EOF
Verify the authentication works by sending a request to the Toy Store API without API key:

```sh
curl -H 'Host: api.toystore.com' http://localhost:9080/toy -i
curl -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy -i
# HTTP/1.1 401 Unauthorized
# www-authenticate: APIKEY realm="api-key-users"
# x-ext-auth-reason: "credential not found"
Expand Down Expand Up @@ -225,13 +235,13 @@ Verify the rate limiting works by sending requests as Alice and Bob.
Up to 5 successful (`200 OK`) requests every 10 seconds allowed for Alice, then `429 Too Many Requests`:

```sh
while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMALICE' -H 'Host: api.toystore.com' http://localhost:9080/toy | egrep --color "\b(429)\b|$"; sleep 1; done
while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMALICE' -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy | grep -E --color "\b(429)\b|$"; sleep 1; done
```

Up to 2 successful (`200 OK`) requests every 10 seconds allowed for Bob, then `429 Too Many Requests`:

```sh
while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMBOB' -H 'Host: api.toystore.com' http://localhost:9080/toy | egrep --color "\b(429)\b|$"; sleep 1; done
while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H 'Authorization: APIKEY IAMBOB' -H 'Host: api.toystore.com' http://$GATEWAY_URL/toy | grep -E --color "\b(429)\b|$"; sleep 1; done
```

## Cleanup
Expand Down
Loading

0 comments on commit 6e985e3

Please sign in to comment.