diff --git a/charts/tfy-agent/Chart.yaml b/charts/tfy-agent/Chart.yaml new file mode 100644 index 000000000..fd181602b --- /dev/null +++ b/charts/tfy-agent/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: tfy-agent +version: 0.1.0 +description: "Truefoundry agent for kubernetes clusters" +maintainers: + - name: truefoundry diff --git a/charts/tfy-agent/templates/_helpers.tpl b/charts/tfy-agent/templates/_helpers.tpl new file mode 100644 index 000000000..b8904d8e0 --- /dev/null +++ b/charts/tfy-agent/templates/_helpers.tpl @@ -0,0 +1,129 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "app.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* + Create a default fully qualified app name. + We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). + If release name contains chart name it will be used as a full name. + */}} +{{- define "app.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Define full name for tfy-agent-proxy +*/}} +{{- define "app.tfyAgentProxy.fullname" -}} +{{- include "app.fullname" . | trunc 57 | trimSuffix "-" }}-proxy +{{- end }} + +{{/* + Create chart name and version as used by the chart label. + */}} +{{- define "app.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* + Common labels + */}} +{{- define "app.labels" -}} +helm.sh/chart: {{ include "app.chart" . }} +{{ include "app.selectorLabels" . }} +{{- if .Values.imageTag }} +app.kubernetes.io/version: {{ .Values.imageTag | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* + Selector labels + */}} +{{- define "app.selectorLabels" -}} +app.kubernetes.io/name: {{ include "app.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* + Create the name of the service account to use + */}} +{{- define "app.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "app.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* + Parse env from template + */}} +{{- define "app.parseEnv" -}} +{{ tpl (.Values.env | toYaml) . }} +{{- end }} + + +{{/* + Create the env file + */}} +{{- define "app.env" }} +{{- range $key, $val := (include "app.parseEnv" .) | fromYaml }} +{{- if and $val (contains "${k8s-secret" ($val | toString)) }} +- name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ $.Values.envSecretName }} + key: {{ $val | trimPrefix "${k8s-secret/" | trimSuffix "}" }} +{{- else }} +- name: {{ $key }} + value: {{ $val | quote }} +{{- end }} +{{- end }} +{{- end }} + +{{/* + Parse env from template + */}} +{{- define "app.tfyAgentProxy.parseEnv" -}} +{{ tpl (.Values.tfyAgentProxy.env | toYaml) . }} +{{- end }} + +{{/* + Create the env file + */}} +{{- define "app.tfyAgentProxy.env" }} +{{- range $key, $val := (include "app.tfyAgentProxy.parseEnv" .) | fromYaml }} +{{- if and $val (contains "${k8s-secret" ($val | toString)) }} +- name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ $.Values.envSecretName }} + key: {{ $val | trimPrefix "${k8s-secret/" | trimSuffix "}" }} +{{- else }} +- name: {{ $key }} + value: {{ $val | quote }} +{{- end }} +{{- end }} +{{- end }} + +# {{- define "app.imagePullSecrets" }} +# {{- if (tpl .Values.imagePullCredentials .) }} +# - name: {{ include "app.fullname" . }}-image-pull-secret +# {{- end }} +# {{- if (tpl .Values.imagePullSecretName .) }} +# - name: {{ tpl .Values.imagePullSecretName . }} +# {{- end }} +# {{- end }} diff --git a/charts/tfy-agent/templates/clusterrolebinding.yaml b/charts/tfy-agent/templates/clusterrolebinding.yaml new file mode 100644 index 000000000..ba81d187f --- /dev/null +++ b/charts/tfy-agent/templates/clusterrolebinding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.rbac.enabled -}} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "app.fullname" . }}-admin-rbac +subjects: + - kind: ServiceAccount + name: {{ include "app.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/tfy-agent/templates/deployment-tfy-agent-proxy.yaml b/charts/tfy-agent/templates/deployment-tfy-agent-proxy.yaml new file mode 100644 index 000000000..003c992fc --- /dev/null +++ b/charts/tfy-agent/templates/deployment-tfy-agent-proxy.yaml @@ -0,0 +1,30 @@ +{{- if .Values.tfyAgentProxy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "app.tfyAgentProxy.fullname" . }} + labels: + app.kubernetes.io/version: {{ .Values.tfyAgentProxy.imageTag | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + helm.sh/chart: {{ include "app.chart" . }} + app.kubernetes.io/name: tfy-agent-proxy +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "app.tfyAgentProxy.fullname" . }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "app.tfyAgentProxy.fullname" . }} + spec: + serviceAccountName: {{ include "app.serviceAccountName" . }} + containers: + - name: tfy-agent-proxy + env: + {{- include "app.tfyAgentProxy.env" . | trim | nindent 12 }} + image: "{{ .Values.tfyAgentProxy.imageRepository }}:{{ .Values.tfyAgentProxy.imageTag }}" + imagePullPolicy: IfNotPresent + resources: + {{- toYaml .Values.tfyAgentProxy.resources | nindent 12 }} +{{- end }} diff --git a/charts/tfy-agent/templates/deployment.yaml b/charts/tfy-agent/templates/deployment.yaml new file mode 100644 index 000000000..4ee9cd45d --- /dev/null +++ b/charts/tfy-agent/templates/deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "app.fullname" . }} + labels: + {{- include "app.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "app.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "app.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "app.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + env: + {{- include "app.env" . | trim | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if .Values.healthcheck.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.healthcheck.liveness.path }} + port: {{ .Values.healthcheck.liveness.port }} + readinessProbe: + httpGet: + path: {{ .Values.healthcheck.readiness.path }} + port: {{ .Values.healthcheck.liveness.port }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/charts/tfy-agent/templates/ingress.yaml b/charts/tfy-agent/templates/ingress.yaml new file mode 100644 index 000000000..1fe0c59d1 --- /dev/null +++ b/charts/tfy-agent/templates/ingress.yaml @@ -0,0 +1,39 @@ +{{- if .Values.ingress.enabled -}} +{{- $serviceName := include "app.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: +{{- if .Values.ingress.annotations }} + annotations: + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + name: {{ include "app.fullname" . }} + labels: + {{- include "app.labels" . | nindent 4 }} + {{- if .Values.ingress.labels }} + {{- toYaml .Values.ingress.labels | nindent 4 }} + {{- end }} +spec: + ingressClassName: {{ .Values.ingress.ingressClassName }} + rules: + {{- range $host := .Values.ingress.hosts }} + - host: {{ $host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + + {{- end -}} + {{- if .Values.ingress.tls }} + tls: + {{- toYaml .Values.ingress.tls | nindent 4 }} + {{- end -}} +{{- end -}} diff --git a/charts/tfy-agent/templates/service.yaml b/charts/tfy-agent/templates/service.yaml new file mode 100644 index 000000000..a45d8822d --- /dev/null +++ b/charts/tfy-agent/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "app.fullname" . }} + labels: + {{- include "app.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.port }} + protocol: TCP + name: http + selector: + {{- include "app.selectorLabels" . | nindent 4 }} \ No newline at end of file diff --git a/charts/tfy-agent/templates/serviceaccount.yaml b/charts/tfy-agent/templates/serviceaccount.yaml new file mode 100644 index 000000000..2519605b9 --- /dev/null +++ b/charts/tfy-agent/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "app.serviceAccountName" . }} + labels: + {{- include "app.labels" . | nindent 4 }} +{{- with .Values.serviceAccount.annotations }} + annotations: +{{ tpl (toYaml . | indent 4) $ }} +{{- end }} +{{- end }} diff --git a/charts/tfy-agent/templates/virtualservice.yaml b/charts/tfy-agent/templates/virtualservice.yaml new file mode 100644 index 000000000..b220274cb --- /dev/null +++ b/charts/tfy-agent/templates/virtualservice.yaml @@ -0,0 +1,32 @@ +{{- if .Values.istio.virtualservice.enabled -}} +{{- $serviceName := include "app.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: {{ include "app.fullname" . }} + labels: + {{- include "app.labels" . | nindent 4 }} + {{- if .Values.istio.virtualservice.annotations }} + annotations: + {{- range $key, $value := .Values.istio.virtualservice.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + namespace: {{ .Release.Namespace }} +spec: + gateways: + {{- range .Values.istio.virtualservice.gateways}} + - {{ . }} + {{- end }} + hosts: + {{- range .Values.istio.virtualservice.hosts}} + - {{ . }} + {{- end }} + http: + - route: + - destination: + host: {{ include "app.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + port: + number: {{ .Values.service.port }} +{{- end }} \ No newline at end of file diff --git a/charts/tfy-agent/values.yaml b/charts/tfy-agent/values.yaml new file mode 100644 index 000000000..d86a277eb --- /dev/null +++ b/charts/tfy-agent/values.yaml @@ -0,0 +1,125 @@ +# Default values for sample. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: {} + +image: + repository: truefoundrycloud/tfy-agent + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "4c0ca0a13b934f81f49ad41a39d3f1e86476511b" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "tfy-agent" + + +envSecretName: tfy-agent-env-secret +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 3000 + annotations: {} + + +ingress: + enabled: false + annotations: {} + labels: {} + ingressClassName: istio + tls: [] + hosts: [] + +resources: + limits: + cpu: 200m + memory: 512Mi + ephemeral-storage: 256Mi + requests: + cpu: 100m + memory: 300Mi + ephemeral-storage: 128Mi + + +healthcheck: + enabled: true + readiness: + port: 3000 + path: / + liveness: + port: 3000 + path: / + +nodeSelector: {} +tolerations: {} +affinity: {} + +istio: + virtualservice: + enabled: false + annotations: {} + gateways: [] + hosts: [] + +rbac: + enabled: true + +name: tfy-agent + +env: + NODE_ENV: production + PROMETHEUS_POLL_INTERVAL: '60000' + PROMETHEUS_ENDPOINT: http://prometheus-operated.prometheus.svc.cluster.local:9090 + OPENCOST_POLL_INTERVAL: '180000' + OPENCOST_ENDPOINT: http://opencost.opencost.svc.cluster.local:9090 + CONTROL_PLANE_URL: '{{ .Values.global.controlPlaneURL }}' + CLUSTER_TOKEN: ${k8s-secret/CLUSTER_TOKEN} + TENANT_NAME: '{{ .Values.global.tenantName }}' + WORKLOAD_NAMESPACE: '{{ .Release.Namespace }}' + CONTROL_PLANE_NATS_PORT: '443' + ALERT_URL: https://auth.truefoundry.com + +tfyAgentProxy: + # specifies if agent proxy should be enabled or not + enabled: true + imageTag: "00f2e71680781ab9e1e64270525b97d01e0ba236" + imageRepository: truefoundrycloud/tfy-agent-proxy + type: ClusterIP + + # resource section for tfy agent proxy + resources: + limits: + cpu: '1' + ephemeral-storage: 500M + memory: 500M + requests: + cpu: 50m + ephemeral-storage: 200M + memory: 100M + + # env variabled to pass to tfy agent proxy + env: + CONTROL_PLANE_URL: '{{ .Values.global.controlPlaneURL }}' + CLUSTER_TOKEN: ${k8s-secret/CLUSTER_TOKEN}