diff --git a/.gitignore b/.gitignore index 68bc17f..1d6f3b2 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,8 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +# Self-signed certs for testing +*.crt +*.key +*.pem \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 6dca988..9437945 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,4 +22,4 @@ RUN echo "$USER_ID:!::0:::::" >>/etc/shadow USER $USER_ID -CMD ["./eric-oss-hello-world-python-app/main.py"] \ No newline at end of file +CMD ["./eric-oss-hello-world-python-app/main.py"] diff --git a/charts/eric-oss-hello-world-python-app/certs/curl-certs.yaml b/charts/eric-oss-hello-world-python-app/certs/curl-certs.yaml new file mode 100644 index 0000000..dde7b70 --- /dev/null +++ b/charts/eric-oss-hello-world-python-app/certs/curl-certs.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + name: curl-certs +data: + ca.crt: xxxxxxxxx + client.crt: xxxxxxxxx + client.key: xxxxxxxxx diff --git a/charts/eric-oss-hello-world-python-app/certs/curl.yaml b/charts/eric-oss-hello-world-python-app/certs/curl.yaml new file mode 100644 index 0000000..975fa5f --- /dev/null +++ b/charts/eric-oss-hello-world-python-app/certs/curl.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: curl +spec: + restartPolicy: Always + containers: + - name: curl + image: curlimages/curl:latest + command: ["sleep", "infinity"] + volumeMounts: + - name: curl-certs + mountPath: /etc/certs + readOnly: true + volumes: + - name: curl-certs + secret: + secretName: curl-certs diff --git a/charts/eric-oss-hello-world-python-app/templates/configmap/configmap-envoy.yaml b/charts/eric-oss-hello-world-python-app/templates/configmap/configmap-envoy.yaml new file mode 100644 index 0000000..82a13a0 --- /dev/null +++ b/charts/eric-oss-hello-world-python-app/templates/configmap/configmap-envoy.yaml @@ -0,0 +1,105 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "eric-oss-hello-world-python-app.name" . }}-envoy-configmap + labels: + {{- include "eric-oss-hello-world-python-app.labels" . | indent 4 }} + {{- if .Values.labels }} + {{ .Values.labels | toYaml | indent 4 }} + {{- end }} + annotations: {{- include "eric-oss-hello-world-python-app.product-info" . | indent 4 }} +data: + envoy.yaml: | + node: + id: {{ .Release.Name }} + cluster: python-hello-world + admin: + address: + socket_address: + address: 0.0.0.0 + port_value: 9901 + static_resources: + listeners: + - name: listener_https + address: + socket_address: + address: 0.0.0.0 + port_value: 8443 + filter_chains: + - transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + require_client_certificate: true + common_tls_context: + tls_certificates: + - certificate_chain: + filename: "/etc/envoy/certs/{{ index .Values.envoy "certFileName" }}" + private_key: + filename: "/etc/envoy/certs/{{ index .Values.envoy "keyFileName" }}" + validation_context: + trusted_ca: + filename: "/etc/envoy/certs/ca.crt" + #For more stricter validation on SAN, uncomment the below and set match_subject_alt_names + #match_subject_alt_names: + # - exact: "client.example.com" + filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress_https_secure + route_config: + name: local_route_https_secure + virtual_hosts: + - name: secure_service + domains: ["*"] + routes: + - match: + prefix: "/sample-app/python/hello" + route: + cluster: eric-oss-hello-world-python-cluster + http_filters: + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + - name: listener_http + address: + socket_address: + address: 0.0.0.0 + port_value: 8080 + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress_http + route_config: + name: local_route_http + virtual_hosts: + - name: backend_http + domains: ["*"] + routes: + - match: + prefix: "/sample-app/python/metrics" + route: + cluster: eric-oss-hello-world-python-cluster + - match: + prefix: "/sample-app/python/health" + route: + cluster: eric-oss-hello-world-python-cluster + http_filters: + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: eric-oss-hello-world-python-cluster + type: STATIC + load_assignment: + cluster_name: eric-oss-hello-world-python-service + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 8050 \ No newline at end of file diff --git a/charts/eric-oss-hello-world-python-app/templates/configmap/configmap.yaml b/charts/eric-oss-hello-world-python-app/templates/configmap/configmap-log-ctrl.yaml similarity index 83% rename from charts/eric-oss-hello-world-python-app/templates/configmap/configmap.yaml rename to charts/eric-oss-hello-world-python-app/templates/configmap/configmap-log-ctrl.yaml index 9c9867f..f522541 100644 --- a/charts/eric-oss-hello-world-python-app/templates/configmap/configmap.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/configmap/configmap-log-ctrl.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ include "eric-oss-hello-world-python-app.name" . }} + name: {{ include "eric-oss-hello-world-python-app.name" . }}-log-ctrl labels: {{- include "eric-oss-hello-world-python-app.labels" . | indent 4 }} {{- if .Values.labels }} diff --git a/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml b/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml index 4aaea3c..167f6cd 100644 --- a/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml @@ -36,9 +36,9 @@ spec: app.kubernetes.io/instance: {{ .Release.Name }} service.cleartext/scraping: "true" annotations: - {{- if not (semverCompare ">=1.30.0" .Capabilities.KubeVersion.GitVersion) }} - container.apparmor.security.beta.kubernetes.io/eric-oss-hello-world-python-app: {{ include "eric-oss-hello-world-python-app.appArmorProfileAnnotation" . | default "runtime/default" }} - {{- end }} +{{/* {{- if not (semverCompare ">=1.30.0" .Capabilities.KubeVersion.GitVersion) }}*/}} +{{/* container.apparmor.security.beta.kubernetes.io/eric-oss-hello-world-python-app: {{ include "eric-oss-hello-world-python-app.appArmorProfileAnnotation" . | default "runtime/default" }}*/}} +{{/* {{- end }}*/}} prometheus.io/port: "{{ .Values.service.port }}" prometheus.io/scrape: "{{ .Values.prometheus.scrape }}" prometheus.io/path: "{{ .Values.prometheus.path }}" @@ -49,53 +49,84 @@ spec: priorityClassName: {{ (index .Values "podPriority" "eric-oss-hello-world-python-app" "priorityClassName") }} {{- end }} volumes: + {{- if eq .Values.profile "minikube" }} + - name: envoy-certs + secret: + secretName: envoy-mtls-secret + {{- end }} - name: config-volume configMap: - name: {{ include "eric-oss-hello-world-python-app.name" . }} + name: {{ include "eric-oss-hello-world-python-app.name" . }}-log-ctrl items: - key: LOG_CTRL_FILE path: logcontrol.json - - name: platform-cacerts - secret: - secretName: {{ index .Values "platformCaCertSecretName" | quote }} - defaultMode: 420 - - name: app-certs - secret: - secretName: {{ index .Values "appSecretName" | quote }} - defaultMode: 420 - - name: client-creds - secret: - secretName: {{ include "eric-oss-hello-world-python-app.clientSecret" . | quote }} - defaultMode: 420 + - name: envoy-config + configMap: + name: {{ include "eric-oss-hello-world-python-app.name" . }}-envoy-configmap + items: + - key: envoy.yaml + path: envoy.yaml +{{/* - name: platform-cacerts*/}} +{{/* secret:*/}} +{{/* secretName: {{ index .Values "platformCaCertSecretName" | quote }}*/}} +{{/* defaultMode: 420*/}} +{{/* - name: app-certs*/}} +{{/* secret:*/}} +{{/* secretName: {{ index .Values "appSecretName" | quote }}*/}} +{{/* defaultMode: 420*/}} +{{/* - name: client-creds*/}} +{{/* secret:*/}} +{{/* secretName: {{ include "eric-oss-hello-world-python-app.clientSecret" . | quote }}*/}} +{{/* defaultMode: 420*/}} containers: + - name: envoy + image: envoyproxy/envoy:v1.35.0 + args: [ "-c", "/etc/envoy/envoy.yaml" ] +{{/* restartPolicy: Always*/}} + ports: + - containerPort: 8080 + name: envoy-http + protocol: TCP + - containerPort: 8443 + name: envoy-https + protocol: TCP + - containerPort: 9901 + name: admin + volumeMounts: + - name: envoy-config + mountPath: /etc/envoy + - name: envoy-certs + mountPath: /etc/envoy/certs + readOnly: true - name: eric-oss-hello-world-python-app image: {{ template "eric-oss-hello-world-python-app.imagePath" (dict "imageId" "eric-oss-hello-world-python-app" "values" .Values "files" .Files) }} imagePullPolicy: {{ include "eric-oss-hello-world-python-app.registryImagePullPolicy" . | quote }} securityContext: - {{- if semverCompare ">=1.30.0" .Capabilities.KubeVersion.GitVersion }} - appArmorProfile: - type: {{ include "eric-oss-hello-world-python-app.appArmorProfile.type" . | default "RuntimeDefault" }} - {{- end }} +{{/* {{- if semverCompare ">=1.30.0" .Capabilities.KubeVersion.GitVersion }} */}} +{{/* appArmorProfile:*/}} +{{/* type: {{ include "eric-oss-hello-world-python-app.appArmorProfile.type" . | default "RuntimeDefault" }}*/}} +{{/* {{- end }}*/}} allowPrivilegeEscalation: false privileged: false readOnlyRootFilesystem: true runAsNonRoot: true capabilities: drop: - - all + - all {{- include "eric-oss-hello-world-python-app.seccomp-profile" . | indent 12 }} - volumeMounts: - - name: config-volume - mountPath: /etc/adp - - name: platform-cacerts - mountPath: {{ index .Values "platformCaCertMountPath" | default .Values.instantiationDefaults.platformCaCertMountPath | quote }} - readOnly: true - - name: app-certs - mountPath: {{ index .Values "appCertMountPath" | default .Values.instantiationDefaults.appCertMountPath | quote }} - readOnly: true - - name: client-creds - mountPath: {{ index .Values "clientCredsMountPath" | default .Values.instantiationDefaults.clientCredsMountPath | quote }} - readOnly: true +{{/* volumeMounts:*/}} +{{/* - name: config-volume*/}} +{{/* mountPath: /etc/adp*/}} +{{/* - name: platform-cacerts*/}} +{{/* mountPath: {{ index .Values "platformCaCertMountPath" | default .Values.instantiationDefaults.platformCaCertMountPath | quote }}*/}} +{{/* readOnly: true*/}} +{{/* - name: app-certs*/}} +{{/* mountPath: {{ index .Values "appCertMountPath" | default .Values.instantiationDefaults.appCertMountPath | quote }}*/}} +{{/* readOnly: true*/}} +{{/* - name: client-creds*/}} +{{/* mountPath: {{ index .Values "clientCredsMountPath" | default .Values.instantiationDefaults.clientCredsMountPath | quote }}*/}} +{{/* readOnly: true*/}} + env: - name: IAM_CLIENT_ID value: {{ index .Values "clientId" | quote }} @@ -108,7 +139,7 @@ spec: - name: CA_CERT_FILE_PATH value: {{ index .Values "platformCaCertMountPath" | default .Values.instantiationDefaults.platformCaCertMountPath | quote }} - name: CA_CERT_FILE_NAME - value: {{ index .Values "platformCaCertFileName" | quote }} + value: {{ index .Values "platformCaCertFileName" | quote }} - name: APP_KEY value: {{ index .Values "appKeyFileName" | quote }} - name: APP_CERT @@ -182,6 +213,22 @@ spec: {{- end }} resources: {{- toYaml .Values.resources.helloWorld | nindent 12 }} +{{/* initContainers:*/}} +{{/* - name: envoy*/}} +{{/* image: envoyproxy/envoy:v1.35.0*/}} +{{/* restartPolicy: Always*/}} +{{/* ports:*/}} +{{/* - containerPort: 8080*/}} +{{/* - containerPort: 8443*/}} +{{/* - containerPort: 9901*/}} +{{/* args: [ "-c", "/etc/envoy/envoy.yaml" ]*/}} +{{/* volumeMounts:*/}} +{{/* - mountPath: /etc/envoy*/}} +{{/* name: config-volume*/}} + +{{/* - name: envoy-certs*/}} +{{/* mountPath: /etc/envoy/certs*/}} +{{/* readOnly: true*/}} {{- if include "eric-oss-hello-world-python-app.pullSecrets" . }} imagePullSecrets: - name: {{ template "eric-oss-hello-world-python-app.pullSecrets" . }} diff --git a/charts/eric-oss-hello-world-python-app/templates/ingress/ingress.yaml b/charts/eric-oss-hello-world-python-app/templates/ingress/ingress.yaml deleted file mode 100644 index ca297c9..0000000 --- a/charts/eric-oss-hello-world-python-app/templates/ingress/ingress.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "eric-oss-hello-world-python-app.name" . -}} -{{- $servicePort := .Values.service.port -}} ---- -apiVersion: networking.k8s.io/v1beta1 -kind: Ingress -metadata: - name: {{ $fullName }} - labels: - {{- include "eric-oss-hello-world-python-app.labels" . | indent 4 }} - {{- if .Values.labels }} - {{ .Values.labels | toYaml | indent 4 }} - {{- end }} - {{- with .Values.ingress }} - annotations: - {{- include "eric-oss-hello-world-python-app.product-info" . | indent 4 }} - {{- if .annotations }} - {{ .annotations | toYaml | indent 4 }} - {{- end }} - {{- if .ingressClass }} - kubernetes.io/ingress.class: {{.ingressClass }} - {{- end -}} - {{- end }} -spec: -{{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} -{{- end }} - rules: - - host: {{ .Values.ingress.host }} - http: - paths: - - path: / - backend: - serviceName: {{ $fullName }} - servicePort: {{ $servicePort }} -{{- end }} diff --git a/charts/eric-oss-hello-world-python-app/templates/network-policy/network-policy.yaml b/charts/eric-oss-hello-world-python-app/templates/network-policy/network-policy.yaml index 142bfe7..e42978b 100644 --- a/charts/eric-oss-hello-world-python-app/templates/network-policy/network-policy.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/network-policy/network-policy.yaml @@ -12,7 +12,10 @@ metadata: spec: podSelector: matchLabels: - app: eric-oss-hello-world-python-app + app.kubernetes.io/name: {{ include "eric-oss-hello-world-python-app.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + policyTypes: + - Ingress ingress: - from: - podSelector: @@ -24,6 +27,12 @@ spec: - podSelector: matchLabels: app: eric-pm-server + {{- if eq .Values.profile "minikube" }} + - podSelector: + matchLabels: + run: curl + {{- end }} ports: - - port: {{ .Values.service.port }} - + - port: 8080 # Envoy HTTP + - port: 8443 # Envoy HTTPS + - port: {{ .Values.service.port }} # Optional: app port (e.g., 8050) diff --git a/charts/eric-oss-hello-world-python-app/templates/secret/envoy-mtls-secret.yaml b/charts/eric-oss-hello-world-python-app/templates/secret/envoy-mtls-secret.yaml new file mode 100644 index 0000000..6121cf6 --- /dev/null +++ b/charts/eric-oss-hello-world-python-app/templates/secret/envoy-mtls-secret.yaml @@ -0,0 +1,13 @@ +{{/* Create a secret with self-signed certs only if we are using the minikube profile. */}} +{{- if eq .Values.profile "minikube" }} +apiVersion: v1 +kind: Secret +metadata: + name: envoy-mtls-secret + namespace: default +type: Opaque +data: + server.crt: {{ .Files.Get "certs/server.crt" | b64enc }} + server.key: {{ .Files.Get "certs/server.key" | b64enc }} + ca.crt: {{ .Files.Get "certs/ca.crt" | b64enc }} +{{- end }} \ No newline at end of file diff --git a/charts/eric-oss-hello-world-python-app/templates/service/service.yaml b/charts/eric-oss-hello-world-python-app/templates/service/service.yaml index d90cef5..36f2427 100644 --- a/charts/eric-oss-hello-world-python-app/templates/service/service.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/service/service.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "eric-oss-hello-world-python-app.name" . }} + name: {{ include "eric-oss-hello-world-python-app.name" . }}-service labels: {{- include "eric-oss-hello-world-python-app.labels" . | indent 4 }} {{- if .Values.labels }} @@ -15,10 +15,18 @@ spec: ipFamilies: [{{ .Values.global.internalIPFamily }}] {{- end }} ports: - - port: {{ .Values.service.port }} - targetPort: 8050 +{{/* - port: {{ .Values.service.port }}*/}} +{{/* targetPort: 8050*/}} +{{/* protocol: TCP*/}} +{{/* name: http*/}} + - port: 8080 + name: envoy-http-svc + targetPort: 8080 + protocol: TCP + - port: 8443 + name: envoy-https-svc + targetPort: 8443 protocol: TCP - name: http selector: app.kubernetes.io/name: {{ include "eric-oss-hello-world-python-app.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/charts/eric-oss-hello-world-python-app/values.yaml b/charts/eric-oss-hello-world-python-app/values.yaml index 2c4b392..5757bd0 100644 --- a/charts/eric-oss-hello-world-python-app/values.yaml +++ b/charts/eric-oss-hello-world-python-app/values.yaml @@ -1,6 +1,8 @@ # Default values for eric-oss-hello-world-python-app. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +profile: "default" + global: timezone: UTC registry: @@ -45,18 +47,6 @@ service: type: ClusterIP port: 8050 -ingress: - enabled: false - ingressClass: OAM-IngressClass - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - host: "" - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - resources: helloWorld: limits: @@ -102,18 +92,22 @@ prometheus: scrape: true path: "/sample-app/python/metrics" +envoy: + certFileName: "server.crt" + keyFileName: "server.key" + terminationGracePeriodSeconds: 30 probes: eric-oss-hello-world-python-app: livenessProbe: failureThreshold: 3 - initialDelaySeconds: 60 + initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 - initialDelaySeconds: 60 + initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 10