diff --git a/dex-auth/dex-crds/base/kustomization.yaml b/dex-auth/dex-crds/base/kustomization.yaml index 0fa67ace38..2111d27db1 100644 --- a/dex-auth/dex-crds/base/kustomization.yaml +++ b/dex-auth/dex-crds/base/kustomization.yaml @@ -80,5 +80,5 @@ configurations: - params.yaml images: - name: quay.io/coreos/dex - newName: quay.io/coreos/dex - newTag: v2.9.0 + newName: gcr.io/arrikto/dexidp/dex + newTag: 4bede5eb80822fc3a7fc9edca0ed2605cd339d17 diff --git a/dex-auth/dex-crds/overlays/istio/kustomization.yaml b/dex-auth/dex-crds/overlays/istio/kustomization.yaml new file mode 100644 index 0000000000..b94f52f8aa --- /dev/null +++ b/dex-auth/dex-crds/overlays/istio/kustomization.yaml @@ -0,0 +1,23 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +bases: +- ../../base +resources: +- virtual-service.yaml + +configMapGenerator: +- name: dex-parameters + behavior: merge + env: params.env +generatorOptions: + disableNameSuffixHash: true +vars: +- name: namespace + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.namespace +configurations: +- params.yaml diff --git a/dex-auth/dex-crds/overlays/istio/params.env b/dex-auth/dex-crds/overlays/istio/params.env new file mode 100644 index 0000000000..ac2dc00963 --- /dev/null +++ b/dex-auth/dex-crds/overlays/istio/params.env @@ -0,0 +1 @@ +namespace=auth \ No newline at end of file diff --git a/dex-auth/dex-crds/overlays/istio/params.yaml b/dex-auth/dex-crds/overlays/istio/params.yaml new file mode 100644 index 0000000000..eea869e0d4 --- /dev/null +++ b/dex-auth/dex-crds/overlays/istio/params.yaml @@ -0,0 +1,3 @@ +varReference: +- path: spec/http/route/destination/host + kind: VirtualService diff --git a/dex-auth/dex-crds/overlays/istio/virtual-service.yaml b/dex-auth/dex-crds/overlays/istio/virtual-service.yaml new file mode 100644 index 0000000000..c84d890884 --- /dev/null +++ b/dex-auth/dex-crds/overlays/istio/virtual-service.yaml @@ -0,0 +1,22 @@ +# This config is gated on kiali upgrade to 0.21 from 0.16 in istio 1.1.6: +# https://github.com/kiali/kiali/issues/1154 +# https://github.com/istio/istio/issues/11131 + +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: dex +spec: + gateways: + - kubeflow/kubeflow-gateway + hosts: + - '*' + http: + - match: + - uri: + prefix: /dex/ + route: + - destination: + host: dex.$(namespace).svc.cluster.local + port: + number: 5556 diff --git a/istio/oidc-authservice/base/deployment.yaml b/istio/oidc-authservice/base/deployment.yaml new file mode 100644 index 0000000000..bf3da7b5b4 --- /dev/null +++ b/istio/oidc-authservice/base/deployment.yaml @@ -0,0 +1,59 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authservice +spec: + replicas: 1 + selector: + matchLabels: + app: authservice + strategy: + type: RollingUpdate + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + labels: + app: authservice + spec: + containers: + - name: authservice + image: gcr.io/arrikto/kubeflow/oidc-authservice:6ac9400 + imagePullPolicy: Always + ports: + - name: http-api + containerPort: 8080 + env: + - name: USERID_HEADER + value: $(userid-header) + - name: USERID_PREFIX + value: $(userid-prefix) + - name: USERID_CLAIM + value: email + - name: OIDC_PROVIDER + value: $(oidc_provider) + - name: OIDC_AUTH_URL + value: $(oidc_auth_url) + - name: OIDC_SCOPES + value: "profile email groups" + - name: REDIRECT_URL + value: $(oidc_redirect_uri) + - name: SKIP_AUTH_URI + value: $(skip_auth_uri) + - name: PORT + value: "8080" + - name: CLIENT_ID + value: $(client_id) + - name: CLIENT_SECRET + value: $(application_secret) + - name: STORE_PATH + value: /var/lib/authservice/data.db + volumeMounts: + - name: data + mountPath: /var/lib/authservice + securityContext: + fsGroup: 111 + volumes: + - name: data + persistentVolumeClaim: + claimName: authservice-pvc diff --git a/istio/oidc-authservice/base/envoy-filter.yaml b/istio/oidc-authservice/base/envoy-filter.yaml new file mode 100644 index 0000000000..7c59538f27 --- /dev/null +++ b/istio/oidc-authservice/base/envoy-filter.yaml @@ -0,0 +1,31 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: authn-filter +spec: + workloadLabels: + istio: ingressgateway + filters: + - filterConfig: + httpService: + serverUri: + uri: http://authservice.$(namespace).svc.cluster.local + cluster: outbound|8080||authservice.$(namespace).svc.cluster.local + failureModeAllow: false + timeout: 10s + authorizationRequest: + allowedHeaders: + patterns: + - exact: "cookie" + authorizationResponse: + allowedUpstreamHeaders: + patterns: + - exact: "kubeflow-userid" + statusOnError: + code: GatewayTimeout + filterName: envoy.ext_authz + filterType: HTTP + insertPosition: + index: FIRST + listenerMatch: + listenerType: GATEWAY diff --git a/istio/oidc-authservice/base/kustomization.yaml b/istio/oidc-authservice/base/kustomization.yaml new file mode 100644 index 0000000000..3a3bee5930 --- /dev/null +++ b/istio/oidc-authservice/base/kustomization.yaml @@ -0,0 +1,87 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- service.yaml +- deployment.yaml +- envoy-filter.yaml +- pvc.yaml + +namespace: istio-system + +configMapGenerator: +- name: oidc-authservice-parameters + env: params.env +generatorOptions: + disableNameSuffixHash: true + +vars: +- name: client_id + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.client_id +- name: oidc_provider + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_provider +- name: oidc_redirect_uri + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_redirect_uri +- name: oidc_auth_url + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_auth_url +- name: application_secret + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.application_secret +- name: skip_auth_uri + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.skip_auth_uri +- name: userid-header + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.userid-header +- name: userid-prefix + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.userid-prefix +- name: namespace + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.namespace +configurations: +- params.yaml +images: +- name: gcr.io/arrikto/kubeflow/oidc-authservice + newName: gcr.io/arrikto/kubeflow/oidc-authservice + newTag: 6ac9400 diff --git a/istio/oidc-authservice/base/params.env b/istio/oidc-authservice/base/params.env new file mode 100644 index 0000000000..9ae6e65cfb --- /dev/null +++ b/istio/oidc-authservice/base/params.env @@ -0,0 +1,9 @@ +client_id=ldapdexapp +oidc_provider= +oidc_redirect_uri= +oidc_auth_url= +application_secret=pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok +skip_auth_uri= +userid-header= +userid-prefix= +namespace=istio-system \ No newline at end of file diff --git a/istio/oidc-authservice/base/params.yaml b/istio/oidc-authservice/base/params.yaml new file mode 100644 index 0000000000..8f14804c95 --- /dev/null +++ b/istio/oidc-authservice/base/params.yaml @@ -0,0 +1,7 @@ +varReference: +- path: spec/template/spec/containers/env/value + kind: Deployment +- path: spec/filters/filterConfig/httpService/serverUri/uri + kind: EnvoyFilter +- path: spec/filters/filterConfig/httpService/serverUri/cluster + kind: EnvoyFilter \ No newline at end of file diff --git a/istio/oidc-authservice/base/pvc.yaml b/istio/oidc-authservice/base/pvc.yaml new file mode 100644 index 0000000000..da2f06ba3a --- /dev/null +++ b/istio/oidc-authservice/base/pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: authservice-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi \ No newline at end of file diff --git a/istio/oidc-authservice/base/service.yaml b/istio/oidc-authservice/base/service.yaml new file mode 100644 index 0000000000..3637beb910 --- /dev/null +++ b/istio/oidc-authservice/base/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: authservice +spec: + type: ClusterIP + selector: + app: authservice + ports: + - port: 8080 + name: http-authservice + targetPort: http-api \ No newline at end of file diff --git a/istio/oidc-authservice/overlays/application/application.yaml b/istio/oidc-authservice/overlays/application/application.yaml new file mode 100644 index 0000000000..08cbb65f81 --- /dev/null +++ b/istio/oidc-authservice/overlays/application/application.yaml @@ -0,0 +1,43 @@ + +apiVersion: app.k8s.io/v1beta1 +kind: Application +metadata: + name: oidc-authservice +spec: + selector: + matchLabels: + app.kubernetes.io/name: oidc-authservice + app.kubernetes.io/instance: oidc-authservice-v0.7.0 + app.kubernetes.io/managed-by: kfctl + app.kubernetes.io/component: oidc-authservice + app.kubernetes.io/part-of: kubeflow + app.kubernetes.io/version: v0.7.0 + componentKinds: + - group: apps + kind: Deployment + - group: core + kind: Service + - group: core + kind: PersistentVolumeClaim + - group: networking.istio.io + kind: EnvoyFilter + descriptor: + type: oidc-authservice + version: v1beta1 + description: Provides OIDC-based authentication for Kubeflow Applications, at the Istio Gateway. + maintainers: + - name: Yannis Zarkadas + email: yanniszark@arrikto.com + owners: + - name: Yannis Zarkadas + email: yanniszark@arrikto.com + keywords: + - oidc + - authservice + - authentication + links: + - description: About + url: https://github.com/kubeflow/kubeflow/tree/master/components/oidc-authservice + - description: Docs + url: https://www.kubeflow.org/docs/started/k8s/kfctl-existing-arrikto + addOwnerRef: true diff --git a/istio/oidc-authservice/overlays/application/kustomization.yaml b/istio/oidc-authservice/overlays/application/kustomization.yaml new file mode 100644 index 0000000000..6d83a87898 --- /dev/null +++ b/istio/oidc-authservice/overlays/application/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +bases: +- ../../base +resources: +- application.yaml +commonLabels: + app.kubernetes.io/name: oidc-authservice + app.kubernetes.io/instance: oidc-authservice-v0.7.0 + app.kubernetes.io/managed-by: kfctl + app.kubernetes.io/component: oidc-authservice + app.kubernetes.io/part-of: kubeflow + app.kubernetes.io/version: v0.7.0 \ No newline at end of file diff --git a/kfdef/kfctl_aws.0.7.0.yaml b/kfdef/kfctl_aws.0.7.0.yaml index e30d0c07d3..45187b9a0f 100644 --- a/kfdef/kfctl_aws.0.7.0.yaml +++ b/kfdef/kfctl_aws.0.7.0.yaml @@ -41,6 +41,75 @@ spec: name: manifests path: application/application name: application + # Istio install. If not needed, comment out istio-crds and istio-install. + - kustomizeConfig: + parameters: + - name: namespace + value: istio-system + repoRef: + name: manifests + path: istio/istio-crds + name: istio-crds + - kustomizeConfig: + parameters: + - name: namespace + value: istio-system + repoRef: + name: manifests + path: istio/istio-install + name: istio-install + # This component is the istio resources for Kubeflow (e.g. gateway), not about installing istio. + - kustomizeConfig: + parameters: + - name: clusterRbacConfig + value: "ON" + repoRef: + name: manifests + path: istio/istio + name: istio + - kustomizeConfig: + overlays: + - application + parameters: + - name: namespace + value: istio-system + - name: userid-header + value: kubeflow-userid + - name: oidc_provider + value: http://dex.auth.svc.cluster.local:5556/dex + - name: oidc_redirect_uri + value: /login/oidc + - name: oidc_auth_url + value: /dex/auth + - name: skip_auth_uri + value: /dex + - name: client_id + value: kubeflow-oidc-authservice + repoRef: + name: manifests + path: istio/oidc-authservice + name: oidc-authservice + - kustomizeConfig: + overlays: + - istio + parameters: + - name: namespace + value: auth + - name: issuer + value: http://dex.auth.svc.cluster.local:5556/dex + - name: client_id + value: kubeflow-oidc-authservice + - name: oidc_redirect_uris + value: '["/login/oidc"]' + - name: static_email + value: admin@kubeflow.org + # Password is "12341234", 12-round bcrypt-hashed. + - name: static_password_hash + value: $2y$12$ruoM7FqXrpVgaol44eRZW.4HWS8SAvg6KYVVSCIwKQPBmTpCm.EeO + repoRef: + name: manifests + path: dex-auth/dex-crds + name: dex - kustomizeConfig: repoRef: name: manifests @@ -301,3 +370,7 @@ spec: - name: manifests uri: https://github.com/kubeflow/manifests/archive/v0.7-branch.tar.gz version: master + name: seldon-core-operator + repos: + - name: manifests + uri: https://github.com/kubeflow/manifests/archive/master.tar.gz diff --git a/tests/dex-crds-base_test.go b/tests/dex-crds-base_test.go index 020972d4c8..4df9971761 100644 --- a/tests/dex-crds-base_test.go +++ b/tests/dex-crds-base_test.go @@ -254,8 +254,8 @@ configurations: - params.yaml images: - name: quay.io/coreos/dex - newName: quay.io/coreos/dex - newTag: v2.9.0 + newName: gcr.io/arrikto/dexidp/dex + newTag: 4bede5eb80822fc3a7fc9edca0ed2605cd339d17 `) } diff --git a/tests/dex-crds-overlays-istio_test.go b/tests/dex-crds-overlays-istio_test.go new file mode 100644 index 0000000000..ddaab963d1 --- /dev/null +++ b/tests/dex-crds-overlays-istio_test.go @@ -0,0 +1,347 @@ +package tests_test + +import ( + "sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/v3/k8sdeps/transformer" + "sigs.k8s.io/kustomize/v3/pkg/fs" + "sigs.k8s.io/kustomize/v3/pkg/loader" + "sigs.k8s.io/kustomize/v3/pkg/plugins" + "sigs.k8s.io/kustomize/v3/pkg/resmap" + "sigs.k8s.io/kustomize/v3/pkg/resource" + "sigs.k8s.io/kustomize/v3/pkg/target" + "sigs.k8s.io/kustomize/v3/pkg/validators" + "testing" +) + +func writeDexCrdsOverlaysIstio(th *KustTestHarness) { + th.writeF("/manifests/dex-auth/dex-crds/overlays/istio/virtual-service.yaml", ` +# This config is gated on kiali upgrade to 0.21 from 0.16 in istio 1.1.6: +# https://github.com/kiali/kiali/issues/1154 +# https://github.com/istio/istio/issues/11131 + +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: dex +spec: + gateways: + - kubeflow/kubeflow-gateway + hosts: + - '*' + http: + - match: + - uri: + prefix: /dex/ + route: + - destination: + host: dex.$(namespace).svc.cluster.local + port: + number: 5556 +`) + th.writeF("/manifests/dex-auth/dex-crds/overlays/istio/params.yaml", ` +varReference: +- path: spec/http/route/destination/host + kind: VirtualService +`) + th.writeF("/manifests/dex-auth/dex-crds/overlays/istio/params.env", ` +namespace=auth`) + th.writeK("/manifests/dex-auth/dex-crds/overlays/istio", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +bases: +- ../../base +resources: +- virtual-service.yaml + +configMapGenerator: +- name: dex-parameters + behavior: merge + env: params.env +generatorOptions: + disableNameSuffixHash: true +vars: +- name: namespace + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.namespace +configurations: +- params.yaml +`) + th.writeF("/manifests/dex-auth/dex-crds/base/namespace.yaml", ` +apiVersion: v1 +kind: Namespace +metadata: + name: auth +`) + th.writeF("/manifests/dex-auth/dex-crds/base/config-map.yaml", ` +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: dex +data: + config.yaml: | + issuer: $(issuer) + storage: + type: kubernetes + config: + inCluster: true + web: + http: 0.0.0.0:5556 + logger: + level: "debug" + format: text + oauth2: + skipApprovalScreen: true + enablePasswordDB: true + staticPasswords: + - email: $(static_email) + hash: $(static_password_hash) + username: $(static_username) + userID: $(static_user_id) + staticClients: + - id: $(client_id) + redirectURIs: $(oidc_redirect_uris) + name: 'Dex Login Application' + secret: $(application_secret) +`) + th.writeF("/manifests/dex-auth/dex-crds/base/crds.yaml", ` +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: authcodes.dex.coreos.com +spec: + group: dex.coreos.com + names: + kind: AuthCode + listKind: AuthCodeList + plural: authcodes + singular: authcode + scope: Namespaced + version: v1 +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: dex +rules: +- apiGroups: ["dex.coreos.com"] # API group created by dex + resources: ["*"] + verbs: ["*"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create"] # To manage its own resources identity must be able to create customresourcedefinitions. +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: dex +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: dex +subjects: +- kind: ServiceAccount + name: dex # Service account assigned to the dex pod. + namespace: auth # The namespace dex is running in. +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: dex + namespace: auth +`) + th.writeF("/manifests/dex-auth/dex-crds/base/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: dex + name: dex +spec: + replicas: 1 + selector: + matchLabels: + app: dex + template: + metadata: + labels: + app: dex + spec: + serviceAccountName: dex + containers: + - image: quay.io/coreos/dex:v2.9.0 + name: dex + command: ["dex", "serve", "/etc/dex/cfg/config.yaml"] + ports: + - name: http + containerPort: 5556 + volumeMounts: + - name: config + mountPath: /etc/dex/cfg + volumes: + - name: config + configMap: + name: dex + items: + - key: config.yaml + path: config.yaml +`) + th.writeF("/manifests/dex-auth/dex-crds/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: dex +spec: + type: NodePort + ports: + - name: dex + port: 5556 + protocol: TCP + targetPort: 5556 + nodePort: 32000 + selector: + app: dex +`) + th.writeF("/manifests/dex-auth/dex-crds/base/params.yaml", ` +varReference: +- path: spec/template/spec/volumes/secret/secretName + kind: Deployment +- path: data/config.yaml + kind: ConfigMap +`) + th.writeF("/manifests/dex-auth/dex-crds/base/params.env", ` +# Dex Server Parameters (some params are shared with client) +dex_domain=dex.example.com +# Set issuer to https if tls is enabled +issuer=http://dex.example.com:32000 +static_email=admin@example.com +static_password_hash=$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W +static_username=admin +static_user_id=08a8684b-db88-4b73-90a9-3cd1661f5466 +client_id=ldapdexapp +oidc_redirect_uris=['http://login.example.org:5555/callback/onprem-cluster'] +application_secret=pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok +`) + th.writeK("/manifests/dex-auth/dex-crds/base", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: auth +resources: +- namespace.yaml +- config-map.yaml +- crds.yaml +- deployment.yaml +- service.yaml +configMapGenerator: +- name: dex-parameters + env: params.env +generatorOptions: + disableNameSuffixHash: true +vars: +- name: dex_domain + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.dex_domain +- name: issuer + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.issuer +- name: static_email + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.static_email +- name: static_password_hash + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.static_password_hash +- name: static_username + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.static_username +- name: static_user_id + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.static_user_id +- name: client_id + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.client_id +- name: oidc_redirect_uris + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_redirect_uris +- name: application_secret + objref: + kind: ConfigMap + name: dex-parameters + apiVersion: v1 + fieldref: + fieldpath: data.application_secret +configurations: +- params.yaml +images: +- name: quay.io/coreos/dex + newName: gcr.io/arrikto/dexidp/dex + newTag: 4bede5eb80822fc3a7fc9edca0ed2605cd339d17 +`) +} + +func TestDexCrdsOverlaysIstio(t *testing.T) { + th := NewKustTestHarness(t, "/manifests/dex-auth/dex-crds/overlays/istio") + writeDexCrdsOverlaysIstio(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + expected, err := m.AsYaml() + if err != nil { + t.Fatalf("Err: %v", err) + } + targetPath := "../dex-auth/dex-crds/overlays/istio" + fsys := fs.MakeRealFS() + lrc := loader.RestrictionRootOnly + _loader, loaderErr := loader.NewLoader(lrc, validators.MakeFakeValidator(), targetPath, fsys) + if loaderErr != nil { + t.Fatalf("could not load kustomize loader: %v", loaderErr) + } + rf := resmap.NewFactory(resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()), transformer.NewFactoryImpl()) + pc := plugins.DefaultPluginConfig() + kt, err := target.NewKustTarget(_loader, rf, transformer.NewFactoryImpl(), plugins.NewLoader(pc, rf)) + if err != nil { + th.t.Fatalf("Unexpected construction error %v", err) + } + actual, err := kt.MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(actual, string(expected)) +} diff --git a/tests/dex-crds-overlays-ldap_test.go b/tests/dex-crds-overlays-ldap_test.go index e57a49cdbd..a895978318 100644 --- a/tests/dex-crds-overlays-ldap_test.go +++ b/tests/dex-crds-overlays-ldap_test.go @@ -448,8 +448,8 @@ configurations: - params.yaml images: - name: quay.io/coreos/dex - newName: quay.io/coreos/dex - newTag: v2.9.0 + newName: gcr.io/arrikto/dexidp/dex + newTag: 4bede5eb80822fc3a7fc9edca0ed2605cd339d17 `) } diff --git a/tests/oidc-authservice-base_test.go b/tests/oidc-authservice-base_test.go new file mode 100644 index 0000000000..938c538c95 --- /dev/null +++ b/tests/oidc-authservice-base_test.go @@ -0,0 +1,273 @@ +package tests_test + +import ( + "sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/v3/k8sdeps/transformer" + "sigs.k8s.io/kustomize/v3/pkg/fs" + "sigs.k8s.io/kustomize/v3/pkg/loader" + "sigs.k8s.io/kustomize/v3/pkg/plugins" + "sigs.k8s.io/kustomize/v3/pkg/resmap" + "sigs.k8s.io/kustomize/v3/pkg/resource" + "sigs.k8s.io/kustomize/v3/pkg/target" + "sigs.k8s.io/kustomize/v3/pkg/validators" + "testing" +) + +func writeOidcAuthserviceBase(th *KustTestHarness) { + th.writeF("/manifests/istio/oidc-authservice/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: authservice +spec: + type: ClusterIP + selector: + app: authservice + ports: + - port: 8080 + name: http-authservice + targetPort: http-api`) + th.writeF("/manifests/istio/oidc-authservice/base/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authservice +spec: + replicas: 1 + selector: + matchLabels: + app: authservice + strategy: + type: RollingUpdate + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + labels: + app: authservice + spec: + containers: + - name: authservice + image: gcr.io/arrikto/kubeflow/oidc-authservice:6ac9400 + imagePullPolicy: Always + ports: + - name: http-api + containerPort: 8080 + env: + - name: USERID_HEADER + value: $(userid-header) + - name: USERID_PREFIX + value: $(userid-prefix) + - name: USERID_CLAIM + value: email + - name: OIDC_PROVIDER + value: $(oidc_provider) + - name: OIDC_AUTH_URL + value: $(oidc_auth_url) + - name: OIDC_SCOPES + value: "profile email groups" + - name: REDIRECT_URL + value: $(oidc_redirect_uri) + - name: SKIP_AUTH_URI + value: $(skip_auth_uri) + - name: PORT + value: "8080" + - name: CLIENT_ID + value: $(client_id) + - name: CLIENT_SECRET + value: $(application_secret) + - name: STORE_PATH + value: /var/lib/authservice/data.db + volumeMounts: + - name: data + mountPath: /var/lib/authservice + securityContext: + fsGroup: 111 + volumes: + - name: data + persistentVolumeClaim: + claimName: authservice-pvc +`) + th.writeF("/manifests/istio/oidc-authservice/base/envoy-filter.yaml", ` +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: authn-filter +spec: + workloadLabels: + istio: ingressgateway + filters: + - filterConfig: + httpService: + serverUri: + uri: http://authservice.$(namespace).svc.cluster.local + cluster: outbound|8080||authservice.$(namespace).svc.cluster.local + failureModeAllow: false + timeout: 10s + authorizationRequest: + allowedHeaders: + patterns: + - exact: "cookie" + authorizationResponse: + allowedUpstreamHeaders: + patterns: + - exact: "kubeflow-userid" + statusOnError: + code: GatewayTimeout + filterName: envoy.ext_authz + filterType: HTTP + insertPosition: + index: FIRST + listenerMatch: + listenerType: GATEWAY +`) + th.writeF("/manifests/istio/oidc-authservice/base/pvc.yaml", ` +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: authservice-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi`) + th.writeF("/manifests/istio/oidc-authservice/base/params.yaml", ` +varReference: +- path: spec/template/spec/containers/env/value + kind: Deployment +- path: spec/filters/filterConfig/httpService/serverUri/uri + kind: EnvoyFilter +- path: spec/filters/filterConfig/httpService/serverUri/cluster + kind: EnvoyFilter`) + th.writeF("/manifests/istio/oidc-authservice/base/params.env", ` +client_id=ldapdexapp +oidc_provider= +oidc_redirect_uri= +oidc_auth_url= +application_secret=pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok +skip_auth_uri= +userid-header= +userid-prefix= +namespace=istio-system`) + th.writeK("/manifests/istio/oidc-authservice/base", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- service.yaml +- deployment.yaml +- envoy-filter.yaml +- pvc.yaml + +namespace: istio-system + +configMapGenerator: +- name: oidc-authservice-parameters + env: params.env +generatorOptions: + disableNameSuffixHash: true + +vars: +- name: client_id + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.client_id +- name: oidc_provider + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_provider +- name: oidc_redirect_uri + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_redirect_uri +- name: oidc_auth_url + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_auth_url +- name: application_secret + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.application_secret +- name: skip_auth_uri + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.skip_auth_uri +- name: userid-header + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.userid-header +- name: userid-prefix + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.userid-prefix +- name: namespace + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.namespace +configurations: +- params.yaml +images: +- name: gcr.io/arrikto/kubeflow/oidc-authservice + newName: gcr.io/arrikto/kubeflow/oidc-authservice + newTag: 6ac9400 +`) +} + +func TestOidcAuthserviceBase(t *testing.T) { + th := NewKustTestHarness(t, "/manifests/istio/oidc-authservice/base") + writeOidcAuthserviceBase(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + expected, err := m.AsYaml() + if err != nil { + t.Fatalf("Err: %v", err) + } + targetPath := "../istio/oidc-authservice/base" + fsys := fs.MakeRealFS() + lrc := loader.RestrictionRootOnly + _loader, loaderErr := loader.NewLoader(lrc, validators.MakeFakeValidator(), targetPath, fsys) + if loaderErr != nil { + t.Fatalf("could not load kustomize loader: %v", loaderErr) + } + rf := resmap.NewFactory(resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()), transformer.NewFactoryImpl()) + pc := plugins.DefaultPluginConfig() + kt, err := target.NewKustTarget(_loader, rf, transformer.NewFactoryImpl(), plugins.NewLoader(pc, rf)) + if err != nil { + th.t.Fatalf("Unexpected construction error %v", err) + } + actual, err := kt.MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(actual, string(expected)) +} diff --git a/tests/oidc-authservice-overlays-application_test.go b/tests/oidc-authservice-overlays-application_test.go new file mode 100644 index 0000000000..51ce47f07b --- /dev/null +++ b/tests/oidc-authservice-overlays-application_test.go @@ -0,0 +1,332 @@ +package tests_test + +import ( + "sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/v3/k8sdeps/transformer" + "sigs.k8s.io/kustomize/v3/pkg/fs" + "sigs.k8s.io/kustomize/v3/pkg/loader" + "sigs.k8s.io/kustomize/v3/pkg/plugins" + "sigs.k8s.io/kustomize/v3/pkg/resmap" + "sigs.k8s.io/kustomize/v3/pkg/resource" + "sigs.k8s.io/kustomize/v3/pkg/target" + "sigs.k8s.io/kustomize/v3/pkg/validators" + "testing" +) + +func writeOidcAuthserviceOverlaysApplication(th *KustTestHarness) { + th.writeF("/manifests/istio/oidc-authservice/overlays/application/application.yaml", ` + +apiVersion: app.k8s.io/v1beta1 +kind: Application +metadata: + name: oidc-authservice +spec: + selector: + matchLabels: + app.kubernetes.io/name: oidc-authservice + app.kubernetes.io/instance: oidc-authservice-v0.7.0 + app.kubernetes.io/managed-by: kfctl + app.kubernetes.io/component: oidc-authservice + app.kubernetes.io/part-of: kubeflow + app.kubernetes.io/version: v0.7.0 + componentKinds: + - group: apps + kind: Deployment + - group: core + kind: Service + - group: core + kind: PersistentVolumeClaim + - group: networking.istio.io + kind: EnvoyFilter + descriptor: + type: oidc-authservice + version: v1beta1 + description: Provides OIDC-based authentication for Kubeflow Applications, at the Istio Gateway. + maintainers: + - name: Yannis Zarkadas + email: yanniszark@arrikto.com + owners: + - name: Yannis Zarkadas + email: yanniszark@arrikto.com + keywords: + - oidc + - authservice + - authentication + links: + - description: About + url: https://github.com/kubeflow/kubeflow/tree/master/components/oidc-authservice + - description: Docs + url: https://www.kubeflow.org/docs/started/k8s/kfctl-existing-arrikto + addOwnerRef: true +`) + th.writeK("/manifests/istio/oidc-authservice/overlays/application", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +bases: +- ../../base +resources: +- application.yaml +commonLabels: + app.kubernetes.io/name: oidc-authservice + app.kubernetes.io/instance: oidc-authservice-v0.7.0 + app.kubernetes.io/managed-by: kfctl + app.kubernetes.io/component: oidc-authservice + app.kubernetes.io/part-of: kubeflow + app.kubernetes.io/version: v0.7.0`) + th.writeF("/manifests/istio/oidc-authservice/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: authservice +spec: + type: ClusterIP + selector: + app: authservice + ports: + - port: 8080 + name: http-authservice + targetPort: http-api`) + th.writeF("/manifests/istio/oidc-authservice/base/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authservice +spec: + replicas: 1 + selector: + matchLabels: + app: authservice + strategy: + type: RollingUpdate + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + labels: + app: authservice + spec: + containers: + - name: authservice + image: gcr.io/arrikto/kubeflow/oidc-authservice:6ac9400 + imagePullPolicy: Always + ports: + - name: http-api + containerPort: 8080 + env: + - name: USERID_HEADER + value: $(userid-header) + - name: USERID_PREFIX + value: $(userid-prefix) + - name: USERID_CLAIM + value: email + - name: OIDC_PROVIDER + value: $(oidc_provider) + - name: OIDC_AUTH_URL + value: $(oidc_auth_url) + - name: OIDC_SCOPES + value: "profile email groups" + - name: REDIRECT_URL + value: $(oidc_redirect_uri) + - name: SKIP_AUTH_URI + value: $(skip_auth_uri) + - name: PORT + value: "8080" + - name: CLIENT_ID + value: $(client_id) + - name: CLIENT_SECRET + value: $(application_secret) + - name: STORE_PATH + value: /var/lib/authservice/data.db + volumeMounts: + - name: data + mountPath: /var/lib/authservice + securityContext: + fsGroup: 111 + volumes: + - name: data + persistentVolumeClaim: + claimName: authservice-pvc +`) + th.writeF("/manifests/istio/oidc-authservice/base/envoy-filter.yaml", ` +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: authn-filter +spec: + workloadLabels: + istio: ingressgateway + filters: + - filterConfig: + httpService: + serverUri: + uri: http://authservice.$(namespace).svc.cluster.local + cluster: outbound|8080||authservice.$(namespace).svc.cluster.local + failureModeAllow: false + timeout: 10s + authorizationRequest: + allowedHeaders: + patterns: + - exact: "cookie" + authorizationResponse: + allowedUpstreamHeaders: + patterns: + - exact: "kubeflow-userid" + statusOnError: + code: GatewayTimeout + filterName: envoy.ext_authz + filterType: HTTP + insertPosition: + index: FIRST + listenerMatch: + listenerType: GATEWAY +`) + th.writeF("/manifests/istio/oidc-authservice/base/pvc.yaml", ` +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: authservice-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi`) + th.writeF("/manifests/istio/oidc-authservice/base/params.yaml", ` +varReference: +- path: spec/template/spec/containers/env/value + kind: Deployment +- path: spec/filters/filterConfig/httpService/serverUri/uri + kind: EnvoyFilter +- path: spec/filters/filterConfig/httpService/serverUri/cluster + kind: EnvoyFilter`) + th.writeF("/manifests/istio/oidc-authservice/base/params.env", ` +client_id=ldapdexapp +oidc_provider= +oidc_redirect_uri= +oidc_auth_url= +application_secret=pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok +skip_auth_uri= +userid-header= +userid-prefix= +namespace=istio-system`) + th.writeK("/manifests/istio/oidc-authservice/base", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- service.yaml +- deployment.yaml +- envoy-filter.yaml +- pvc.yaml + +namespace: istio-system + +configMapGenerator: +- name: oidc-authservice-parameters + env: params.env +generatorOptions: + disableNameSuffixHash: true + +vars: +- name: client_id + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.client_id +- name: oidc_provider + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_provider +- name: oidc_redirect_uri + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_redirect_uri +- name: oidc_auth_url + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.oidc_auth_url +- name: application_secret + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.application_secret +- name: skip_auth_uri + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.skip_auth_uri +- name: userid-header + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.userid-header +- name: userid-prefix + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.userid-prefix +- name: namespace + objref: + kind: ConfigMap + name: oidc-authservice-parameters + apiVersion: v1 + fieldref: + fieldpath: data.namespace +configurations: +- params.yaml +images: +- name: gcr.io/arrikto/kubeflow/oidc-authservice + newName: gcr.io/arrikto/kubeflow/oidc-authservice + newTag: 6ac9400 +`) +} + +func TestOidcAuthserviceOverlaysApplication(t *testing.T) { + th := NewKustTestHarness(t, "/manifests/istio/oidc-authservice/overlays/application") + writeOidcAuthserviceOverlaysApplication(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + expected, err := m.AsYaml() + if err != nil { + t.Fatalf("Err: %v", err) + } + targetPath := "../istio/oidc-authservice/overlays/application" + fsys := fs.MakeRealFS() + lrc := loader.RestrictionRootOnly + _loader, loaderErr := loader.NewLoader(lrc, validators.MakeFakeValidator(), targetPath, fsys) + if loaderErr != nil { + t.Fatalf("could not load kustomize loader: %v", loaderErr) + } + rf := resmap.NewFactory(resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()), transformer.NewFactoryImpl()) + pc := plugins.DefaultPluginConfig() + kt, err := target.NewKustTarget(_loader, rf, transformer.NewFactoryImpl(), plugins.NewLoader(pc, rf)) + if err != nil { + th.t.Fatalf("Unexpected construction error %v", err) + } + actual, err := kt.MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(actual, string(expected)) +}