diff --git a/cmd/ark/main.go b/cmd/ark/main.go new file mode 100644 index 00000000..18f19838 --- /dev/null +++ b/cmd/ark/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/jetstack/preflight/cmd" + +func main() { + cmd.Execute() +} diff --git a/deploy/charts/cyberark-disco-agent/.helmignore b/deploy/charts/cyberark-disco-agent/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/deploy/charts/cyberark-disco-agent/Chart.yaml b/deploy/charts/cyberark-disco-agent/Chart.yaml new file mode 100644 index 00000000..f02b6bf0 --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: cyberark-disco-agent +description: |- + The cyberark-disco-agent connects your Kubernetes or Openshift cluster to CyberArk Discovery and Context. + +maintainers: + - name: CyberArk + email: support@cyberark.com + url: https://cyberark.com + +sources: + - https://github.com/jetstack/jetstack-secure + +# These versions are meant to be overridden by `make helm-chart`. No `v` prefix +# for the `version` because Helm doesn't support auto-determining the latest +# version for OCI Helm charts that use a `v` prefix. +version: 0.0.0 +appVersion: "v0.0.0" diff --git a/deploy/charts/cyberark-disco-agent/README.md b/deploy/charts/cyberark-disco-agent/README.md new file mode 100644 index 00000000..79e7e19a --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/README.md @@ -0,0 +1,383 @@ +# cyberark-disco-agent + +The Cyberark Discovery and Context Agent connects your Kubernetes or OpenShift +cluster to the Discovery and Context service of the CyberArk Identity Security Platform. + +## Quick Start + +### Create a Namespace + +Create a namespace for the agent: + +```sh +export NAMESPACE=cyberark +kubectl create ns "$NAMESPACE" || true +``` + +### Add credentials to a Secret + +You will require tenant details and credentials for the CyberArk Identity Security Platform. +Put them in the following environment variables: + +```sh +export ARK_SUBDOMAIN= # your CyberArk tenant subdomain e.g. tlskp-test +export ARK_USERNAME= # your CyberArk username +export ARK_SECRET= # your CyberArk password +# OPTIONAL: the URL for the CyberArk Discovery API if not using the production environment +export ARK_DISCOVERY_API=https://platform-discovery.integration-cyberark.cloud/ +``` + +Create a Secret containing the tenant details and credentials: + +```sh +kubectl create secret generic agent-credentials \ + --namespace "$NAMESPACE" \ + --from-literal=ARK_USERNAME=$ARK_USERNAME \ + --from-literal=ARK_SECRET=$ARK_SECRET \ + --from-literal=ARK_SUBDOMAIN=$ARK_SUBDOMAIN \ + --from-literal=ARK_DISCOVERY_API=$ARK_DISCOVERY_API +``` + +Alternatively, use the following Secret as a template: + +```yaml +# agent-credentials.yaml +apiVersion: v1 +kind: Secret +metadata: + name: agent-credentials + namespace: cyberark +type: Opaque +stringData: + ARK_SUBDOMAIN: $ARK_SUBDOMAIN # your CyberArk tenant subdomain e.g. tlskp-test + ARK_SECRET: $ARK_SECRET # your CyberArk password + ARK_USERNAME: $ARK_USERNAME # your CyberArk username + # OPTIONAL: the URL for the CyberArk Discovery API if not using the production environment + # ARK_DISCOVERY_API: https://platform-discovery.integration-cyberark.cloud/ +``` + +### Deploy the agent + +Deploy the agent: + +```sh +helm upgrade agent "oci://${OCI_BASE}/charts/cyberark-disco-agent" \ + --install \ + --create-namespace \ + --namespace "$NAMESPACE" \ + --set fullnameOverride=disco-agent +``` + +### Troubleshooting + +Check the Pod and its events: +```sh +kubectl describe -n cyberark pods -l app.kubernetes.io/name=cyberark-disco-agent +``` + +Check the logs: +```sh +kubectl logs deployments/disco-agent --namespace "${NAMESPACE}" --follow +``` + +## Values + + + +#### **replicaCount** ~ `number` +> Default value: +> ```yaml +> 1 +> ``` + +This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +#### **image.repository** ~ `string` +> Default value: +> ```yaml +> "" +> ``` +#### **image.pullPolicy** ~ `string` +> Default value: +> ```yaml +> IfNotPresent +> ``` + +This sets the pull policy for images. +#### **image.tag** ~ `string` +> Default value: +> ```yaml +> "" +> ``` + +Overrides the image tag whose default is the chart appVersion. +#### **image.digest** ~ `string` +> Default value: +> ```yaml +> "" +> ``` + +The image digest +#### **imagePullSecrets** ~ `array` +> Default value: +> ```yaml +> [] +> ``` + +This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +#### **nameOverride** ~ `string` +> Default value: +> ```yaml +> "" +> ``` + +This is to override the chart name. +#### **fullnameOverride** ~ `string` +> Default value: +> ```yaml +> "" +> ``` +#### **serviceAccount.create** ~ `bool` +> Default value: +> ```yaml +> true +> ``` + +Specifies whether a service account should be created +#### **serviceAccount.automount** ~ `bool` +> Default value: +> ```yaml +> true +> ``` + +Automatically mount a ServiceAccount's API credentials? +#### **serviceAccount.annotations** ~ `object` +> Default value: +> ```yaml +> {} +> ``` + +Annotations to add to the service account +#### **serviceAccount.name** ~ `string` +> Default value: +> ```yaml +> "" +> ``` + +The name of the service account to use. +If not set and create is true, a name is generated using the fullname template +#### **podAnnotations** ~ `object` +> Default value: +> ```yaml +> {} +> ``` + +This is for setting Kubernetes Annotations to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +#### **podLabels** ~ `object` +> Default value: +> ```yaml +> {} +> ``` + +This is for setting Kubernetes Labels to a Pod. +For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +#### **podSecurityContext** ~ `object` +> Default value: +> ```yaml +> {} +> ``` +#### **securityContext** ~ `object` +> Default value: +> ```yaml +> allowPrivilegeEscalation: false +> capabilities: +> drop: +> - ALL +> readOnlyRootFilesystem: true +> runAsNonRoot: true +> seccompProfile: +> type: RuntimeDefault +> ``` + +Add Container specific SecurityContext settings to the container. Takes precedence over `podSecurityContext` when set. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container + +#### **resources** ~ `object` +> Default value: +> ```yaml +> {} +> ``` +#### **volumes** ~ `array` +> Default value: +> ```yaml +> [] +> ``` + +Additional volumes on the output Deployment definition. +#### **volumeMounts** ~ `array` +> Default value: +> ```yaml +> [] +> ``` + +Additional volumeMounts on the output Deployment definition. +#### **nodeSelector** ~ `object` +> Default value: +> ```yaml +> {} +> ``` +#### **tolerations** ~ `array` +> Default value: +> ```yaml +> [] +> ``` +#### **affinity** ~ `object` +> Default value: +> ```yaml +> {} +> ``` +#### **http_proxy** ~ `string` + +Configures the HTTP_PROXY environment variable where a HTTP proxy is required. + +#### **https_proxy** ~ `string` + +Configures the HTTPS_PROXY environment variable where a HTTP proxy is required. + +#### **no_proxy** ~ `string` + +Configures the NO_PROXY environment variable where a HTTP proxy is required, but certain domains should be excluded. + +#### **podDisruptionBudget** ~ `object` +> Default value: +> ```yaml +> enabled: false +> ``` + +Configure a PodDisruptionBudget for the agent's Deployment. If running with multiple replicas, consider setting podDisruptionBudget.enabled to true. + +#### **config.period** ~ `string` +> Default value: +> ```yaml +> 1h0m0s +> ``` + +Push data every hour unless changed. +#### **config.excludeAnnotationKeysRegex** ~ `array` +> Default value: +> ```yaml +> [] +> ``` + +You can configure the agent to exclude some annotations or labels from being pushed . All Kubernetes objects are affected. The objects are still pushed, but the specified annotations and labels are removed before being pushed. + +Dots is the only character that needs to be escaped in the regex. Use either double quotes with escaped single quotes or unquoted strings for the regex to avoid YAML parsing issues with `\.`. + +Example: excludeAnnotationKeysRegex: ['^kapp\.k14s\.io/original.*'] +#### **config.excludeLabelKeysRegex** ~ `array` +> Default value: +> ```yaml +> [] +> ``` +#### **authentication.secretName** ~ `string` +> Default value: +> ```yaml +> agent-credentials +> ``` +#### **extraArgs** ~ `array` +> Default value: +> ```yaml +> [] +> ``` + +```yaml +extraArgs: +- --logging-format=json +- --log-level=6 # To enable HTTP request logging +``` +#### **pprof.enabled** ~ `bool` +> Default value: +> ```yaml +> false +> ``` + +Enable profiling with the pprof endpoint +#### **metrics.enabled** ~ `bool` +> Default value: +> ```yaml +> true +> ``` + +Enable the metrics server. +If false, the metrics server will be disabled and the other metrics fields below will be ignored. +#### **metrics.podmonitor.enabled** ~ `bool` +> Default value: +> ```yaml +> false +> ``` + +Create a PodMonitor to add the metrics to Prometheus, if you are using Prometheus Operator. See https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor +#### **metrics.podmonitor.namespace** ~ `string` + +The namespace that the pod monitor should live in. +Defaults to the cyberark-disco-agent namespace. + +#### **metrics.podmonitor.prometheusInstance** ~ `string` +> Default value: +> ```yaml +> default +> ``` + +Specifies the `prometheus` label on the created PodMonitor. This is used when different Prometheus instances have label selectors matching different PodMonitors. +#### **metrics.podmonitor.interval** ~ `string` +> Default value: +> ```yaml +> 60s +> ``` + +The interval to scrape metrics. +#### **metrics.podmonitor.scrapeTimeout** ~ `string` +> Default value: +> ```yaml +> 30s +> ``` + +The timeout before a metrics scrape fails. +#### **metrics.podmonitor.labels** ~ `object` +> Default value: +> ```yaml +> {} +> ``` + +Additional labels to add to the PodMonitor. +#### **metrics.podmonitor.annotations** ~ `object` +> Default value: +> ```yaml +> {} +> ``` + +Additional annotations to add to the PodMonitor. +#### **metrics.podmonitor.honorLabels** ~ `bool` +> Default value: +> ```yaml +> false +> ``` + +Keep labels from scraped data, overriding server-side labels. +#### **metrics.podmonitor.endpointAdditionalProperties** ~ `object` +> Default value: +> ```yaml +> {} +> ``` + +EndpointAdditionalProperties allows setting additional properties on the endpoint such as relabelings, metricRelabelings etc. + +For example: + +```yaml +endpointAdditionalProperties: + relabelings: + - action: replace + sourceLabels: + - __meta_kubernetes_pod_node_name + targetLabel: instance +``` + diff --git a/deploy/charts/cyberark-disco-agent/templates/NOTES.txt b/deploy/charts/cyberark-disco-agent/templates/NOTES.txt new file mode 100644 index 00000000..2aea6a74 --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/NOTES.txt @@ -0,0 +1,9 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +- Check the application is running: +> kubectl get pods -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} + +- Check the application logs for successful connection to the platform: +> kubectl logs -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} diff --git a/deploy/charts/cyberark-disco-agent/templates/_helpers.tpl b/deploy/charts/cyberark-disco-agent/templates/_helpers.tpl new file mode 100644 index 00000000..1a43b7cf --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cyberark-disco-agent.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 "cyberark-disco-agent.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 }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "cyberark-disco-agent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "cyberark-disco-agent.labels" -}} +helm.sh/chart: {{ include "cyberark-disco-agent.chart" . }} +{{ include "cyberark-disco-agent.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "cyberark-disco-agent.selectorLabels" -}} +app.kubernetes.io/name: {{ include "cyberark-disco-agent.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cyberark-disco-agent.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "cyberark-disco-agent.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/deploy/charts/cyberark-disco-agent/templates/configmap.yaml b/deploy/charts/cyberark-disco-agent/templates/configmap.yaml new file mode 100644 index 00000000..d9703168 --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/configmap.yaml @@ -0,0 +1,107 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +data: + config.yaml: |- + period: {{ .Values.config.period | quote }} + {{- with .Values.config.excludeAnnotationKeysRegex }} + exclude-annotation-keys-regex: + {{- . | toYaml | nindent 6 }} + {{- end }} + {{- with .Values.config.excludeLabelKeysRegex }} + exclude-label-keys-regex: + {{- . | toYaml | nindent 6 }} + {{- end }} + data-gatherers: + - kind: k8s-discovery + name: ark/discovery + - kind: k8s-dynamic + name: ark/secrets + config: + resource-type: + version: v1 + resource: secrets + field-selectors: + - type!=kubernetes.io/dockercfg + - type!=kubernetes.io/dockerconfigjson + - type!=bootstrap.kubernetes.io/token + - type!=helm.sh/release.v1 + - kind: k8s-dynamic + name: ark/serviceaccounts + config: + resource-type: + resource: serviceaccounts + version: v1 + - kind: k8s-dynamic + name: ark/roles + config: + resource-type: + version: v1 + group: rbac.authorization.k8s.io + resource: roles + - kind: k8s-dynamic + name: ark/clusterroles + config: + resource-type: + version: v1 + group: rbac.authorization.k8s.io + resource: clusterroles + - kind: k8s-dynamic + name: ark/rolebindings + config: + resource-type: + version: v1 + group: rbac.authorization.k8s.io + resource: rolebindings + - kind: k8s-dynamic + name: ark/clusterrolebindings + config: + resource-type: + version: v1 + group: rbac.authorization.k8s.io + resource: clusterrolebindings + - kind: k8s-dynamic + name: ark/jobs + config: + resource-type: + version: v1 + group: batch + resource: jobs + - kind: k8s-dynamic + name: ark/cronjobs + config: + resource-type: + version: v1 + group: batch + resource: cronjobs + - kind: k8s-dynamic + name: ark/deployments + config: + resource-type: + version: v1 + group: apps + resource: deployments + - kind: k8s-dynamic + name: ark/statefulsets + config: + resource-type: + version: v1 + group: apps + resource: statefulsets + - kind: k8s-dynamic + name: ark/daemonsets + config: + resource-type: + version: v1 + group: apps + resource: daemonsets + - kind: k8s-dynamic + name: ark/pods + config: + resource-type: + version: v1 + resource: pods diff --git a/deploy/charts/cyberark-disco-agent/templates/deployment.yaml b/deploy/charts/cyberark-disco-agent/templates/deployment.yaml new file mode 100644 index 00000000..98e9bc26 --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/deployment.yaml @@ -0,0 +1,139 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }} + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "cyberark-disco-agent.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "cyberark-disco-agent.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: agent + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}{{- with .Values.image.digest }}@{{ . }}{{- end }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + - name: POD_NODE + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ARK_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.authentication.secretName }} + key: ARK_USERNAME + - name: ARK_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.authentication.secretName }} + key: ARK_SECRET + - name: ARK_SUBDOMAIN + valueFrom: + secretKeyRef: + name: {{ .Values.authentication.secretName }} + key: ARK_SUBDOMAIN + - name: ARK_DISCOVERY_API + valueFrom: + secretKeyRef: + name: {{ .Values.authentication.secretName }} + key: ARK_DISCOVERY_API + optional: true + {{- with .Values.http_proxy }} + - name: HTTP_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.https_proxy }} + - name: HTTPS_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.no_proxy }} + - name: NO_PROXY + value: {{ . }} + {{- end }} + args: + - "agent" + - "-c" + - "/etc/cyberark-disco-agent/config.yaml" + - --machine-hub + - --logging-format=json + {{- if .Values.metrics.enabled }} + - --enable-metrics + {{- end }} + {{- if .Values.pprof.enabled }} + - --enable-pprof + {{- end }} + {{- range .Values.extraArgs }} + - {{ . | quote }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: "/etc/cyberark-disco-agent" + readOnly: true + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: agent-api + containerPort: 8081 + volumes: + - name: config + configMap: + name: {{ include "cyberark-disco-agent.fullname" . }}-config + optional: false + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- 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 }} diff --git a/deploy/charts/cyberark-disco-agent/templates/poddisruptionbudget.yaml b/deploy/charts/cyberark-disco-agent/templates/poddisruptionbudget.yaml new file mode 100644 index 00000000..fb8c73eb --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/poddisruptionbudget.yaml @@ -0,0 +1,23 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "cyberark-disco-agent.selectorLabels" . | nindent 6 }} + + {{- if not (or (hasKey .Values.podDisruptionBudget "minAvailable") (hasKey .Values.podDisruptionBudget "maxUnavailable")) }} + minAvailable: 1 # Default value because minAvailable and maxUnavailable are not set + {{- end }} + {{- if hasKey .Values.podDisruptionBudget "minAvailable" }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if hasKey .Values.podDisruptionBudget "maxUnavailable" }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} +{{- end }} diff --git a/deploy/charts/cyberark-disco-agent/templates/podmonitor.yaml b/deploy/charts/cyberark-disco-agent/templates/podmonitor.yaml new file mode 100644 index 00000000..b486e02b --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/podmonitor.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.metrics.enabled .Values.metrics.podmonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }} +{{- if .Values.metrics.podmonitor.namespace }} + namespace: {{ .Values.metrics.podmonitor.namespace }} +{{- else }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} + prometheus: {{ .Values.metrics.podmonitor.prometheusInstance }} + {{- with .Values.metrics.podmonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.metrics.podmonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + jobLabel: {{ include "cyberark-disco-agent.fullname" . }} + selector: + matchLabels: + {{- include "cyberark-disco-agent.selectorLabels" . | nindent 6 }} +{{- if .Values.metrics.podmonitor.namespace }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} +{{- end }} + podMetricsEndpoints: + - port: agent-api + path: /metrics + interval: {{ .Values.metrics.podmonitor.interval }} + scrapeTimeout: {{ .Values.metrics.podmonitor.scrapeTimeout }} + honorLabels: {{ .Values.metrics.podmonitor.honorLabels }} + {{- with .Values.metrics.podmonitor.endpointAdditionalProperties }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/deploy/charts/cyberark-disco-agent/templates/rbac.yaml b/deploy/charts/cyberark-disco-agent/templates/rbac.yaml new file mode 100644 index 00000000..b0a0c7be --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/rbac.yaml @@ -0,0 +1,98 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-event-emitted + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-event-emitted + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "cyberark-disco-agent.fullname" . }}-event-emitted +subjects: + - kind: ServiceAccount + name: {{ include "cyberark-disco-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-cluster-viewer + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: view +subjects: + - kind: ServiceAccount + name: {{ include "cyberark-disco-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-secret-reader + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-secret-reader + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +roleRef: + kind: ClusterRole + name: {{ include "cyberark-disco-agent.fullname" . }}-secret-reader + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ include "cyberark-disco-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-rbac-reader + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +rules: + - apiGroups: ["rbac.authorization.k8s.io"] + resources: + - roles + - clusterroles + - rolebindings + - clusterrolebindings + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "cyberark-disco-agent.fullname" . }}-rbac-reader + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} +roleRef: + kind: ClusterRole + name: {{ include "cyberark-disco-agent.fullname" . }}-rbac-reader + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ include "cyberark-disco-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + diff --git a/deploy/charts/cyberark-disco-agent/templates/serviceaccount.yaml b/deploy/charts/cyberark-disco-agent/templates/serviceaccount.yaml new file mode 100644 index 00000000..a69e9643 --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "cyberark-disco-agent.serviceAccountName" . }} + labels: + {{- include "cyberark-disco-agent.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/deploy/charts/cyberark-disco-agent/values.linter.exceptions b/deploy/charts/cyberark-disco-agent/values.linter.exceptions new file mode 100644 index 00000000..e69de29b diff --git a/deploy/charts/cyberark-disco-agent/values.schema.json b/deploy/charts/cyberark-disco-agent/values.schema.json new file mode 100644 index 00000000..93bd388e --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/values.schema.json @@ -0,0 +1,425 @@ +{ + "$defs": { + "helm-values": { + "additionalProperties": false, + "properties": { + "affinity": { + "$ref": "#/$defs/helm-values.affinity" + }, + "authentication": { + "$ref": "#/$defs/helm-values.authentication" + }, + "config": { + "$ref": "#/$defs/helm-values.config" + }, + "extraArgs": { + "$ref": "#/$defs/helm-values.extraArgs" + }, + "fullnameOverride": { + "$ref": "#/$defs/helm-values.fullnameOverride" + }, + "global": { + "$ref": "#/$defs/helm-values.global" + }, + "http_proxy": { + "$ref": "#/$defs/helm-values.http_proxy" + }, + "https_proxy": { + "$ref": "#/$defs/helm-values.https_proxy" + }, + "image": { + "$ref": "#/$defs/helm-values.image" + }, + "imagePullSecrets": { + "$ref": "#/$defs/helm-values.imagePullSecrets" + }, + "metrics": { + "$ref": "#/$defs/helm-values.metrics" + }, + "nameOverride": { + "$ref": "#/$defs/helm-values.nameOverride" + }, + "no_proxy": { + "$ref": "#/$defs/helm-values.no_proxy" + }, + "nodeSelector": { + "$ref": "#/$defs/helm-values.nodeSelector" + }, + "podAnnotations": { + "$ref": "#/$defs/helm-values.podAnnotations" + }, + "podDisruptionBudget": { + "$ref": "#/$defs/helm-values.podDisruptionBudget" + }, + "podLabels": { + "$ref": "#/$defs/helm-values.podLabels" + }, + "podSecurityContext": { + "$ref": "#/$defs/helm-values.podSecurityContext" + }, + "pprof": { + "$ref": "#/$defs/helm-values.pprof" + }, + "replicaCount": { + "$ref": "#/$defs/helm-values.replicaCount" + }, + "resources": { + "$ref": "#/$defs/helm-values.resources" + }, + "securityContext": { + "$ref": "#/$defs/helm-values.securityContext" + }, + "serviceAccount": { + "$ref": "#/$defs/helm-values.serviceAccount" + }, + "tolerations": { + "$ref": "#/$defs/helm-values.tolerations" + }, + "volumeMounts": { + "$ref": "#/$defs/helm-values.volumeMounts" + }, + "volumes": { + "$ref": "#/$defs/helm-values.volumes" + } + }, + "type": "object" + }, + "helm-values.affinity": { + "default": {}, + "type": "object" + }, + "helm-values.authentication": { + "additionalProperties": false, + "properties": { + "secretName": { + "$ref": "#/$defs/helm-values.authentication.secretName" + } + }, + "type": "object" + }, + "helm-values.authentication.secretName": { + "default": "agent-credentials", + "type": "string" + }, + "helm-values.config": { + "additionalProperties": false, + "properties": { + "excludeAnnotationKeysRegex": { + "$ref": "#/$defs/helm-values.config.excludeAnnotationKeysRegex" + }, + "excludeLabelKeysRegex": { + "$ref": "#/$defs/helm-values.config.excludeLabelKeysRegex" + }, + "period": { + "$ref": "#/$defs/helm-values.config.period" + } + }, + "type": "object" + }, + "helm-values.config.excludeAnnotationKeysRegex": { + "default": [], + "description": "You can configure the agent to exclude some annotations or labels from being pushed . All Kubernetes objects are affected. The objects are still pushed, but the specified annotations and labels are removed before being pushed.\n\nDots is the only character that needs to be escaped in the regex. Use either double quotes with escaped single quotes or unquoted strings for the regex to avoid YAML parsing issues with `\\.`.\n\nExample: excludeAnnotationKeysRegex: ['^kapp\\.k14s\\.io/original.*']", + "items": {}, + "type": "array" + }, + "helm-values.config.excludeLabelKeysRegex": { + "default": [], + "items": {}, + "type": "array" + }, + "helm-values.config.period": { + "default": "1h0m0s", + "description": "Push data every hour unless changed.", + "type": "string" + }, + "helm-values.extraArgs": { + "default": [], + "description": "extraArgs:\n- --logging-format=json\n- --log-level=6 # To enable HTTP request logging", + "items": {}, + "type": "array" + }, + "helm-values.fullnameOverride": { + "default": "", + "type": "string" + }, + "helm-values.global": { + "description": "Global values shared across all (sub)charts" + }, + "helm-values.http_proxy": { + "description": "Configures the HTTP_PROXY environment variable where a HTTP proxy is required.", + "type": "string" + }, + "helm-values.https_proxy": { + "description": "Configures the HTTPS_PROXY environment variable where a HTTP proxy is required.", + "type": "string" + }, + "helm-values.image": { + "additionalProperties": false, + "properties": { + "digest": { + "$ref": "#/$defs/helm-values.image.digest" + }, + "pullPolicy": { + "$ref": "#/$defs/helm-values.image.pullPolicy" + }, + "repository": { + "$ref": "#/$defs/helm-values.image.repository" + }, + "tag": { + "$ref": "#/$defs/helm-values.image.tag" + } + }, + "type": "object" + }, + "helm-values.image.digest": { + "default": "", + "description": "The image digest", + "type": "string" + }, + "helm-values.image.pullPolicy": { + "default": "IfNotPresent", + "description": "This sets the pull policy for images.", + "type": "string" + }, + "helm-values.image.repository": { + "default": "", + "type": "string" + }, + "helm-values.image.tag": { + "default": "", + "description": "Overrides the image tag whose default is the chart appVersion.", + "type": "string" + }, + "helm-values.imagePullSecrets": { + "default": [], + "description": "This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/", + "items": {}, + "type": "array" + }, + "helm-values.metrics": { + "additionalProperties": false, + "properties": { + "enabled": { + "$ref": "#/$defs/helm-values.metrics.enabled" + }, + "podmonitor": { + "$ref": "#/$defs/helm-values.metrics.podmonitor" + } + }, + "type": "object" + }, + "helm-values.metrics.enabled": { + "default": true, + "description": "Enable the metrics server.\nIf false, the metrics server will be disabled and the other metrics fields below will be ignored.", + "type": "boolean" + }, + "helm-values.metrics.podmonitor": { + "additionalProperties": false, + "properties": { + "annotations": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.annotations" + }, + "enabled": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.enabled" + }, + "endpointAdditionalProperties": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.endpointAdditionalProperties" + }, + "honorLabels": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.honorLabels" + }, + "interval": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.interval" + }, + "labels": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.labels" + }, + "namespace": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.namespace" + }, + "prometheusInstance": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.prometheusInstance" + }, + "scrapeTimeout": { + "$ref": "#/$defs/helm-values.metrics.podmonitor.scrapeTimeout" + } + }, + "type": "object" + }, + "helm-values.metrics.podmonitor.annotations": { + "default": {}, + "description": "Additional annotations to add to the PodMonitor.", + "type": "object" + }, + "helm-values.metrics.podmonitor.enabled": { + "default": false, + "description": "Create a PodMonitor to add the metrics to Prometheus, if you are using Prometheus Operator. See https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor", + "type": "boolean" + }, + "helm-values.metrics.podmonitor.endpointAdditionalProperties": { + "default": {}, + "description": "EndpointAdditionalProperties allows setting additional properties on the endpoint such as relabelings, metricRelabelings etc.\n\nFor example:\nendpointAdditionalProperties:\n relabelings:\n - action: replace\n sourceLabels:\n - __meta_kubernetes_pod_node_name\n targetLabel: instance", + "type": "object" + }, + "helm-values.metrics.podmonitor.honorLabels": { + "default": false, + "description": "Keep labels from scraped data, overriding server-side labels.", + "type": "boolean" + }, + "helm-values.metrics.podmonitor.interval": { + "default": "60s", + "description": "The interval to scrape metrics.", + "type": "string" + }, + "helm-values.metrics.podmonitor.labels": { + "default": {}, + "description": "Additional labels to add to the PodMonitor.", + "type": "object" + }, + "helm-values.metrics.podmonitor.namespace": { + "description": "The namespace that the pod monitor should live in.\nDefaults to the cyberark-disco-agent namespace.", + "type": "string" + }, + "helm-values.metrics.podmonitor.prometheusInstance": { + "default": "default", + "description": "Specifies the `prometheus` label on the created PodMonitor. This is used when different Prometheus instances have label selectors matching different PodMonitors.", + "type": "string" + }, + "helm-values.metrics.podmonitor.scrapeTimeout": { + "default": "30s", + "description": "The timeout before a metrics scrape fails.", + "type": "string" + }, + "helm-values.nameOverride": { + "default": "", + "description": "This is to override the chart name.", + "type": "string" + }, + "helm-values.no_proxy": { + "description": "Configures the NO_PROXY environment variable where a HTTP proxy is required, but certain domains should be excluded.", + "type": "string" + }, + "helm-values.nodeSelector": { + "default": {}, + "type": "object" + }, + "helm-values.podAnnotations": { + "default": {}, + "description": "This is for setting Kubernetes Annotations to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/", + "type": "object" + }, + "helm-values.podDisruptionBudget": { + "default": { + "enabled": false + }, + "description": "Configure a PodDisruptionBudget for the agent's Deployment. If running with multiple replicas, consider setting podDisruptionBudget.enabled to true.", + "type": "object" + }, + "helm-values.podLabels": { + "default": {}, + "description": "This is for setting Kubernetes Labels to a Pod.\nFor more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", + "type": "object" + }, + "helm-values.podSecurityContext": { + "default": {}, + "type": "object" + }, + "helm-values.pprof": { + "additionalProperties": false, + "properties": { + "enabled": { + "$ref": "#/$defs/helm-values.pprof.enabled" + } + }, + "type": "object" + }, + "helm-values.pprof.enabled": { + "default": false, + "description": "Enable profiling with the pprof endpoint", + "type": "boolean" + }, + "helm-values.replicaCount": { + "default": 1, + "description": "This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/", + "type": "number" + }, + "helm-values.resources": { + "default": {}, + "type": "object" + }, + "helm-values.securityContext": { + "default": { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + }, + "readOnlyRootFilesystem": true, + "runAsNonRoot": true, + "seccompProfile": { + "type": "RuntimeDefault" + } + }, + "description": "Add Container specific SecurityContext settings to the container. Takes precedence over `podSecurityContext` when set. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container", + "type": "object" + }, + "helm-values.serviceAccount": { + "additionalProperties": false, + "properties": { + "annotations": { + "$ref": "#/$defs/helm-values.serviceAccount.annotations" + }, + "automount": { + "$ref": "#/$defs/helm-values.serviceAccount.automount" + }, + "create": { + "$ref": "#/$defs/helm-values.serviceAccount.create" + }, + "name": { + "$ref": "#/$defs/helm-values.serviceAccount.name" + } + }, + "type": "object" + }, + "helm-values.serviceAccount.annotations": { + "default": {}, + "description": "Annotations to add to the service account", + "type": "object" + }, + "helm-values.serviceAccount.automount": { + "default": true, + "description": "Automatically mount a ServiceAccount's API credentials?", + "type": "boolean" + }, + "helm-values.serviceAccount.create": { + "default": true, + "description": "Specifies whether a service account should be created", + "type": "boolean" + }, + "helm-values.serviceAccount.name": { + "default": "", + "description": "The name of the service account to use.\nIf not set and create is true, a name is generated using the fullname template", + "type": "string" + }, + "helm-values.tolerations": { + "default": [], + "items": {}, + "type": "array" + }, + "helm-values.volumeMounts": { + "default": [], + "description": "Additional volumeMounts on the output Deployment definition.", + "items": {}, + "type": "array" + }, + "helm-values.volumes": { + "default": [], + "description": "Additional volumes on the output Deployment definition.", + "items": {}, + "type": "array" + } + }, + "$ref": "#/$defs/helm-values", + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/deploy/charts/cyberark-disco-agent/values.yaml b/deploy/charts/cyberark-disco-agent/values.yaml new file mode 100644 index 00000000..79b7a670 --- /dev/null +++ b/deploy/charts/cyberark-disco-agent/values.yaml @@ -0,0 +1,197 @@ +# Default values for cyberark-disco-agent. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + repository: "" + # This sets the pull policy for images. + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + # The image digest + digest: "" + +# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# This is to override the chart name. +nameOverride: "" +fullnameOverride: "" + +# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: 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: "" + +# This is for setting Kubernetes Annotations to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# This is for setting Kubernetes Labels to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +podSecurityContext: {} + # fsGroup: 2000 + +# Add Container specific SecurityContext settings to the container. Takes +# precedence over `podSecurityContext` when set. See +# https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container +# +docs:property +securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + seccompProfile: { type: RuntimeDefault } + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +# Additional volumes on the output Deployment definition. +volumes: [] +# - name: foo +# secret: +# secretName: mysecret +# optional: false + +# Additional volumeMounts on the output Deployment definition. +volumeMounts: [] +# - name: foo +# mountPath: "/etc/foo" +# readOnly: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Configures the HTTP_PROXY environment variable where a HTTP proxy is required. +# +docs:property +# http_proxy: "http://proxy:8080" + +# Configures the HTTPS_PROXY environment variable where a HTTP proxy is required. +# +docs:property +# https_proxy: "https://proxy:8080" + +# Configures the NO_PROXY environment variable where a HTTP proxy is required, +# but certain domains should be excluded. +# +docs:property +# no_proxy: 127.0.0.1,localhost + +# Configure a PodDisruptionBudget for the agent's Deployment. If running with multiple +# replicas, consider setting podDisruptionBudget.enabled to true. +# +docs:property +podDisruptionBudget: + # Enable or disable the PodDisruptionBudget resource, which helps prevent downtime + # during voluntary disruptions such as during a Node upgrade. + enabled: false + + # Configure the minimum available pods for disruptions. Can either be set to + # an integer (e.g. 1) or a percentage value (e.g. 25%). + # Cannot be used if `maxUnavailable` is set. + # +docs:property + # minAvailable: 1 + + # Configure the maximum unavailable pods for disruptions. Can either be set to + # an integer (e.g. 1) or a percentage value (e.g. 25%). + # Cannot be used if `minAvailable` is set. + # +docs:property + # maxUnavailable: 1 + +# Configuration for the agent +config: + # Push data every hour unless changed. + period: "1h0m0s" + + # You can configure the agent to exclude some annotations or + # labels from being pushed . All Kubernetes objects + # are affected. The objects are still pushed, but the specified annotations + # and labels are removed before being pushed. + # + # Dots is the only character that needs to be escaped in the regex. Use either + # double quotes with escaped single quotes or unquoted strings for the regex + # to avoid YAML parsing issues with `\.`. + # + # Example: excludeAnnotationKeysRegex: ['^kapp\.k14s\.io/original.*'] + excludeAnnotationKeysRegex: [] + excludeLabelKeysRegex: [] + +authentication: + secretName: agent-credentials + +# extraArgs: +# - --logging-format=json +# - --log-level=6 # To enable HTTP request logging +extraArgs: [] + +pprof: + # Enable profiling with the pprof endpoint + enabled: false + +metrics: + # Enable the metrics server. + # If false, the metrics server will be disabled and the other metrics fields below will be ignored. + enabled: true + podmonitor: + # Create a PodMonitor to add the metrics to Prometheus, if you are using Prometheus Operator. + # See https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor + enabled: false + + # The namespace that the pod monitor should live in. + # Defaults to the cyberark-disco-agent namespace. + # +docs:property + # namespace: cyberark + + # Specifies the `prometheus` label on the created PodMonitor. + # This is used when different Prometheus instances have label selectors + # matching different PodMonitors. + prometheusInstance: default + + # The interval to scrape metrics. + interval: 60s + + # The timeout before a metrics scrape fails. + scrapeTimeout: 30s + + # Additional labels to add to the PodMonitor. + labels: {} + + # Additional annotations to add to the PodMonitor. + annotations: {} + + # Keep labels from scraped data, overriding server-side labels. + honorLabels: false + + # EndpointAdditionalProperties allows setting additional properties on the endpoint such as relabelings, metricRelabelings etc. + # + # For example: + # endpointAdditionalProperties: + # relabelings: + # - action: replace + # sourceLabels: + # - __meta_kubernetes_pod_node_name + # targetLabel: instance + endpointAdditionalProperties: {} + diff --git a/examples/machinehub.yaml b/examples/machinehub.yaml index d53cd099..ea0b28e5 100644 --- a/examples/machinehub.yaml +++ b/examples/machinehub.yaml @@ -24,11 +24,8 @@ data-gatherers: version: v1 resource: secrets field-selectors: - - type!=kubernetes.io/service-account-token - type!=kubernetes.io/dockercfg - type!=kubernetes.io/dockerconfigjson - - type!=kubernetes.io/basic-auth - - type!=kubernetes.io/ssh-auth - type!=bootstrap.kubernetes.io/token - type!=helm.sh/release.v1 diff --git a/hack/ark/test-e2e.sh b/hack/ark/test-e2e.sh new file mode 100755 index 00000000..7cc1f7da --- /dev/null +++ b/hack/ark/test-e2e.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# +# Build and deploy the cyberark-disco-agent Helm chart. +# Wait for the agent to log a message indicating successful data upload. +# +# Prerequisites: +# * kubectl: https://kubernetes.io/docs/tasks/tools/#kubectl +# * kind: https://kind.sigs.k8s.io/docs/user/quick-start/ +# * helm: https://helm.sh/docs/intro/install/ +# * jq: https://jqlang.github.io/jq/download/ +# * make: https://www.gnu.org/software/make/ +# +# You can run `make ark-test-e2e` which will automatically download all +# prerequisites and then run this script. + +set -o nounset +set -o errexit +set -o pipefail + +# CyberArk API configuration +: ${ARK_USERNAME?} +: ${ARK_SECRET?} +: ${ARK_SUBDOMAIN?} +: ${ARK_DISCOVERY_API?} + +# The base URL of the OCI registry used for Docker images and Helm charts +# E.g. ttl.sh/7e6ca67c-96dc-4dea-9437-80b0f3a69fb1 +: ${OCI_BASE?} + +# The Kubernetes namespace to install into +: ${NAMESPACE:=cyberark} + +# Set to true to use an existing cluster, otherwise a new kind cluster will be created. +# Note: the cluster will not be deleted after the test completes. +: ${USE_EXISTING_CLUSTER:=false} + +script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +root_dir=$(cd "${script_dir}/../.." && pwd) +export TERM=dumb + +tmp_dir="$(mktemp -d /tmp/jetstack-secure.XXXXX)" +trap 'rm -rf "${tmp_dir}"' EXIT + +pushd "${tmp_dir}" +> release.env +make -C "$root_dir" ark-release GITHUB_OUTPUT="${tmp_dir}/release.env" +cat release.env +source release.env + +if [[ "$USE_EXISTING_CLUSTER" != true ]]; then + kind create cluster || true +fi + +kubectl create ns "$NAMESPACE" || true + +kubectl delete secret agent-credentials --namespace "$NAMESPACE" --ignore-not-found +kubectl create secret generic agent-credentials \ + --namespace "$NAMESPACE" \ + --from-literal=ARK_USERNAME=$ARK_USERNAME \ + --from-literal=ARK_SECRET=$ARK_SECRET \ + --from-literal=ARK_SUBDOMAIN=$ARK_SUBDOMAIN \ + --from-literal=ARK_DISCOVERY_API=$ARK_DISCOVERY_API + +helm upgrade agent "oci://${RELEASE_OCI_CHART}@${RELEASE_OCI_CHART_DIGEST}" \ + --version "${RELEASE_OCI_CHART_TAG}" \ + --install \ + --wait \ + --create-namespace \ + --namespace "$NAMESPACE" \ + --set pprof.enabled=true \ + --set fullnameOverride=disco-agent \ + --set "image.digest=${RELEASE_OCI_IMAGE_DIGEST}" \ + --set-json "podLabels={\"disco-agent.cyberark.cloud/test-id\": \"${RANDOM}\"}" + +kubectl rollout status deployments/disco-agent --namespace "${NAMESPACE}" + +# Wait 60s for log message indicating success. +# Parse logs as JSON using jq to ensure logs are all JSON formatted. +timeout 60 jq -n \ + 'inputs | if .msg | test("Data sent successfully") then . | halt_error(0) else . end' \ + <(kubectl logs deployments/disco-agent --namespace "${NAMESPACE}" --follow) + +# Query the Prometheus metrics endpoint to ensure it's working. +kubectl get pod \ + --namespace cyberark \ + --selector app.kubernetes.io/name=cyberark-disco-agent \ + --output jsonpath={.items[*].metadata.name} \ + | xargs -I{} kubectl get --raw /api/v1/namespaces/cyberark/pods/{}:8081/proxy/metrics \ + | grep '^process_' + +# Query the pprof endpoint to ensure it's working. +kubectl get pod \ + --namespace cyberark \ + --selector app.kubernetes.io/name=cyberark-disco-agent \ + --output jsonpath={.items[*].metadata.name} \ + | xargs -I{} kubectl get --raw /api/v1/namespaces/cyberark/pods/{}:8081/proxy/debug/pprof/cmdline \ + | xargs -0 + diff --git a/make/00_mod.mk b/make/00_mod.mk index 232c5796..368b821b 100644 --- a/make/00_mod.mk +++ b/make/00_mod.mk @@ -46,12 +46,15 @@ helm_labels_template_name := preflight.labels # locally. We provide the targets in this repo instead, and manually maintain the workflow. govulncheck_skip := true +helm_image_name ?= $(oci_preflight_image_name) +helm_image_tag ?= $(oci_preflight_image_tag) + # Allows us to replace the Helm values.yaml's image.repository and image.tag # with the right values. define helm_values_mutation_function $(YQ) \ - '( .image.repository = "$(oci_preflight_image_name)" ) | \ - ( .image.tag = "$(oci_preflight_image_tag)" )' \ + '( .image.repository = "$(helm_image_name)" ) | \ + ( .image.tag = "$(helm_image_tag)" )' \ $1 --inplace endef @@ -59,3 +62,4 @@ golangci_lint_config := .golangci.yaml go_header_file := /dev/null include make/extra_tools.mk +include make/ark/00_mod.mk diff --git a/make/02_mod.mk b/make/02_mod.mk index 5bd58aee..c23c2ee2 100644 --- a/make/02_mod.mk +++ b/make/02_mod.mk @@ -1,4 +1,5 @@ include make/test-unit.mk +include make/ark/02_mod.mk GITHUB_OUTPUT ?= /dev/stderr .PHONY: release diff --git a/make/ark/00_mod.mk b/make/ark/00_mod.mk new file mode 100644 index 00000000..a89f1a47 --- /dev/null +++ b/make/ark/00_mod.mk @@ -0,0 +1,33 @@ +build_names += ark +go_ark_main_dir := ./cmd/ark +go_ark_mod_dir := . +go_ark_ldflags := \ + -X $(repo_name)/pkg/version.PreflightVersion=$(VERSION) \ + -X $(repo_name)/pkg/version.Commit=$(GITCOMMIT) \ + -X $(repo_name)/pkg/version.BuildDate=$(shell date "+%F-%T-%Z") \ + +oci_ark_base_image_flavor := static +oci_ark_image_name := quay.io/jetstack/ark-agent +oci_ark_image_tag := $(VERSION) +oci_ark_image_name_development := jetstack.local/ark-agent + +# Annotations are the standardised set of annotations we set on every component we publish +oci_ark_build_args := \ + --image-annotation="org.opencontainers.image.source"="https://github.com/jetstack/jetstack-secure" \ + --image-annotation="org.opencontainers.image.vendor"="CyberArk Software Ltd." \ + --image-annotation="org.opencontainers.image.licenses"="EULA - https://www.cyberark.com/contract-terms/" \ + --image-annotation="org.opencontainers.image.authors"="TODO" \ + --image-annotation="org.opencontainers.image.title"="CyberArk Discovery and Context Agent" \ + --image-annotation="org.opencontainers.image.description"="Gathers machine identity data from Kubernetes clusters." \ + --image-annotation="org.opencontainers.image.url"="TODO" \ + --image-annotation="org.opencontainers.image.documentation"="TODO" \ + --image-annotation="org.opencontainers.image.version"="$(VERSION)" \ + --image-annotation="org.opencontainers.image.revision"="$(GITCOMMIT)" + + +define ark_helm_values_mutation_function +$(YQ) \ + '( .image.repository = "$(oci_ark_image_name)" ) | \ + ( .image.tag = "$(oci_ark_image_tag)" )' \ + $1 --inplace +endef diff --git a/make/ark/02_mod.mk b/make/ark/02_mod.mk new file mode 100644 index 00000000..62cb9314 --- /dev/null +++ b/make/ark/02_mod.mk @@ -0,0 +1,63 @@ +.PHONY: ark-generate-helm-docs +## Generate Helm chart documentation. +## @category CyberArk Discovery and Context +ark-generate-helm-docs: helm_chart_source_dir := deploy/charts/cyberark-disco-agent +ark-generate-helm-docs: generate-helm-docs + +shared_generate_targets += ark-generate-helm-docs + +.PHONY: ark-generate-helm-schema +## Generate Helm chart schema. +## @category CyberArk Discovery and Context +ark-generate-helm-schema: helm_chart_source_dir := deploy/charts/cyberark-disco-agent +ark-generate-helm-schema: generate-helm-schema + +shared_generate_targets += ark-generate-helm-schema + +GITHUB_OUTPUT ?= /dev/stderr +.PHONY: ark-release +## Publish all release artifacts (image + helm chart) +## @category CyberArk Discovery and Context +ark-release: oci_ark_image_name := $(OCI_BASE)/images/cyberark-disco-agent +ark-release: OCI_SIGN_ON_PUSH := false +ark-release: oci_platforms := linux/amd64 +ark-release: helm_chart_source_dir := deploy/charts/cyberark-disco-agent +ark-release: helm_chart_image_name := $(OCI_BASE)/charts/cyberark-disco-agent +ark-release: helm_chart_version := $(helm_chart_version) +ark-release: oci_ark_image_digest_path := $(bin_dir)/scratch/image/oci-layout-ark.digests +ark-release: helm_digest_path := $(bin_dir)/scratch/helm/cyberark-disco-agent-$(helm_chart_version).digests +ark-release: + $(MAKE) oci-push-ark helm-chart-oci-push \ + oci_ark_image_name="$(oci_ark_image_name)" \ + OCI_SIGN_ON_PUSH="$(OCI_SIGN_ON_PUSH)" \ + oci_platforms="$(oci_platforms)" \ + helm_image_name="$(oci_ark_image_name)" \ + helm_image_tag="$(oci_ark_image_tag)" \ + helm_chart_source_dir="$(helm_chart_source_dir)" \ + helm_chart_image_name="$(helm_chart_image_name)" + + @echo "RELEASE_OCI_IMAGE=$(oci_ark_image_name)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_IMAGE_TAG=$(oci_ark_image_tag)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_IMAGE_DIGEST=$$(head -1 $(oci_ark_image_digest_path))" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_CHART=$(helm_chart_image_name)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_CHART_TAG=$(helm_chart_version)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_CHART_DIGEST=$$(head -1 $(helm_digest_path))" >> "$(GITHUB_OUTPUT)" + + @echo "Release complete!" + +.PHONY: ark-test-e2e +## Run a basic E2E test on a Kind cluster +## See `hack/ark/e2e.sh` for the full test script. +## @category CyberArk Discovery and Context +ark-test-e2e: $(NEEDS_KIND) $(NEEDS_KUBECTL) $(NEEDS_HELM) + PATH="$(bin_dir)/tools:${PATH}" ./hack/ark/test-e2e.sh + +.PHONY: ark-verify +## Verify the Helm chart +## @category CyberArk Discovery and Context +ark-verify: + $(MAKE) verify-helm-lint verify-helm-values verify-pod-security-standards verify-helm-kubeconform\ + helm_chart_source_dir=deploy/charts/cyberark-disco-agent \ + helm_chart_image_name=$(OCI_BASE)/charts/cyberark-disco-agent + +shared_verify_targets_dirty += ark-verify