From e8eb5fd3974149c3b640256a33436f612766795a Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 5 Aug 2024 15:35:04 +0200 Subject: [PATCH] Add opencost Signed-off-by: Andrei Kvapil --- packages/system/opencost/Chart.yaml | 3 + packages/system/opencost/Makefile | 10 + .../opencost/charts/opencost/Chart.yaml | 19 + .../system/opencost/charts/opencost/README.md | 213 ++++++++ .../opencost/charts/opencost/README.md.gotmpl | 26 + .../charts/opencost/templates/_helpers.tpl | 182 +++++++ .../opencost/templates/clusterrole.yaml | 79 +++ .../templates/clusterrolebinding.yaml | 18 + .../templates/configmap-custom-pricing.yaml | 15 + .../templates/configmap-metrics-config.yaml | 11 + .../charts/opencost/templates/deployment.yaml | 390 +++++++++++++ .../charts/opencost/templates/ingress.yaml | 40 ++ .../opencost/templates/install-plugins.yaml | 46 ++ .../opencost/templates/networkpolicy.yaml | 49 ++ .../opencost/templates/plugins-config.yaml | 16 + .../charts/opencost/templates/pvc.yaml | 18 + .../charts/opencost/templates/secret.yaml | 30 + .../charts/opencost/templates/service.yaml | 48 ++ .../opencost/templates/serviceaccount.yaml | 12 + .../opencost/templates/servicemonitor.yaml | 42 ++ .../opencost/tests/deployment_test.yaml | 16 + .../charts/opencost/tests/opencost_test.yaml | 7 + .../charts/opencost/tests/service_test.yaml | 29 + .../opencost/charts/opencost/values.yaml | 512 ++++++++++++++++++ .../opencost/templates/vmservicescrape.yaml | 11 + packages/system/opencost/values.yaml | 12 + 26 files changed, 1854 insertions(+) create mode 100644 packages/system/opencost/Chart.yaml create mode 100644 packages/system/opencost/Makefile create mode 100644 packages/system/opencost/charts/opencost/Chart.yaml create mode 100644 packages/system/opencost/charts/opencost/README.md create mode 100644 packages/system/opencost/charts/opencost/README.md.gotmpl create mode 100644 packages/system/opencost/charts/opencost/templates/_helpers.tpl create mode 100644 packages/system/opencost/charts/opencost/templates/clusterrole.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/clusterrolebinding.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/configmap-custom-pricing.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/configmap-metrics-config.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/deployment.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/ingress.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/install-plugins.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/networkpolicy.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/plugins-config.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/pvc.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/secret.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/service.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/serviceaccount.yaml create mode 100644 packages/system/opencost/charts/opencost/templates/servicemonitor.yaml create mode 100644 packages/system/opencost/charts/opencost/tests/deployment_test.yaml create mode 100644 packages/system/opencost/charts/opencost/tests/opencost_test.yaml create mode 100644 packages/system/opencost/charts/opencost/tests/service_test.yaml create mode 100644 packages/system/opencost/charts/opencost/values.yaml create mode 100644 packages/system/opencost/templates/vmservicescrape.yaml create mode 100644 packages/system/opencost/values.yaml diff --git a/packages/system/opencost/Chart.yaml b/packages/system/opencost/Chart.yaml new file mode 100644 index 00000000..ebe68045 --- /dev/null +++ b/packages/system/opencost/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozy-opencost +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/opencost/Makefile b/packages/system/opencost/Makefile new file mode 100644 index 00000000..cfef2167 --- /dev/null +++ b/packages/system/opencost/Makefile @@ -0,0 +1,10 @@ +export NAME=opencost +export NAMESPACE=cozy-$(NAME) + +include ../../../scripts/package-system.mk + +update: + rm -rf charts + helm repo add opencost-charts https://opencost.github.io/opencost-helm-chart + helm repo update opencost-charts + helm pull opencost-charts/opencost --untar --untardir charts diff --git a/packages/system/opencost/charts/opencost/Chart.yaml b/packages/system/opencost/charts/opencost/Chart.yaml new file mode 100644 index 00000000..e6853670 --- /dev/null +++ b/packages/system/opencost/charts/opencost/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v2 +appVersion: 1.111.0 +description: OpenCost and OpenCost UI +home: https://github.com/opencost/opencost-helm-chart +keywords: +- cloud-costs +- cost-optimization +- finops +- monitoring +- opencost +maintainers: +- name: mattray + url: https://mattray.dev +- name: toscott +- email: rafa@stormforge.io + name: brito-rafa +name: opencost +type: application +version: 1.41.0 diff --git a/packages/system/opencost/charts/opencost/README.md b/packages/system/opencost/charts/opencost/README.md new file mode 100644 index 00000000..69c7d453 --- /dev/null +++ b/packages/system/opencost/charts/opencost/README.md @@ -0,0 +1,213 @@ +# opencost + +OpenCost and OpenCost UI + +![Version: 1.41.0](https://img.shields.io/badge/Version-1.41.0-informational?style=flat-square) +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) +![AppVersion: 1.111.0](https://img.shields.io/badge/AppVersion-1.111.0-informational?style=flat-square) +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/opencost)](https://artifacthub.io/packages/search?repo=opencost) +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/opencost-oci)](https://artifacthub.io/packages/search?repo=opencost-oci) + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| mattray | | | +| toscott | | | +| brito-rafa | | | + +## Installing the Chart + +To install the chart with the release name `opencost`: + +```console +$ helm install opencost opencost/opencost +``` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| annotations | object | `{}` | Annotations to add to the all the resources | +| extraVolumes | list | `[]` | A list of volumes to be added to the pod | +| fullnameOverride | string | `""` | Overwrite all resources name created by the chart | +| imagePullSecrets | list | `[]` | List of secret names to use for pulling the images | +| loglevel | string | `"info"` | | +| nameOverride | string | `""` | Overwrite the default name of the chart | +| namespaceOverride | string | `""` | Override the deployment namespace | +| networkPolicies.enabled | bool | `false` | Specifies whether networkpolicies should be created | +| networkPolicies.extraEgress | list | `[]` | Extra egress rule | +| networkPolicies.prometheus | object | `{"labels":{"app.kubernetes.io/name":"prometheus"},"namespace":"prometheus-system","port":9090}` | Internal Prometheus settings related to NetworkPolicies | +| networkPolicies.prometheus.labels | object | `{"app.kubernetes.io/name":"prometheus"}` | Labels applied to the Prometheus server pod(s) | +| networkPolicies.prometheus.namespace | string | `"prometheus-system"` | Namespace where internal Prometheus is installed | +| networkPolicies.prometheus.port | int | `9090` | Pod port of in-cluster Prometheus | +| opencost.affinity | object | `{}` | Affinity settings for pod assignment | +| opencost.carbonCost.enabled | bool | `false` | Enable carbon cost exposed in the API | +| opencost.cloudCost.enabled | bool | `false` | Enable cloud cost ingestion and querying, dependant on valid integration credentials | +| opencost.cloudCost.monthToDateInterval | int | `6` | The number of standard runs before a Month-to-Date run occurs | +| opencost.cloudCost.queryWindowDays | int | `7` | The max number of days that any single query will be made to construct Cloud Costs | +| opencost.cloudCost.refreshRateHours | int | `6` | Number of hours between each run of the Cloud Cost pipeline | +| opencost.cloudCost.runWindowDays | int | `3` | Number of days into the past that a Cloud Cost standard run will query for | +| opencost.cloudIntegrationSecret | string | `""` | | +| opencost.customPricing.configPath | string | `"/tmp/custom-config"` | Path for the pricing configuration. | +| opencost.customPricing.configmapName | string | `"custom-pricing-model"` | Customize the configmap name used for custom pricing | +| opencost.customPricing.costModel | object | `{"CPU":1.25,"GPU":0.95,"RAM":0.5,"description":"Modified pricing configuration.","internetNetworkEgress":0.12,"regionNetworkEgress":0.01,"spotCPU":0.006655,"spotRAM":0.000892,"storage":0.25,"zoneNetworkEgress":0.01}` | More information about these values here: https://www.opencost.io/docs/configuration/on-prem#custom-pricing-using-the-opencost-helm-chart | +| opencost.customPricing.createConfigmap | bool | `true` | Configures the pricing model provided in the values file. | +| opencost.customPricing.enabled | bool | `false` | Enables custom pricing configuration | +| opencost.customPricing.provider | string | `"custom"` | Sets the provider type for the custom pricing file. | +| opencost.dataRetention.dailyResolutionDays | int | `15` | | +| opencost.exporter.apiPort | int | `9003` | | +| opencost.exporter.aws.access_key_id | string | `""` | AWS secret key id | +| opencost.exporter.aws.secret_access_key | string | `""` | AWS secret access key | +| opencost.exporter.cloudProviderApiKey | string | `""` | The GCP Pricing API requires a key. This is supplied just for evaluation. | +| opencost.exporter.csv_path | string | `""` | | +| opencost.exporter.defaultClusterId | string | `"default-cluster"` | Default cluster ID to use if cluster_id is not set in Prometheus metrics. | +| opencost.exporter.env | list | `[]` | List of additional environment variables to set in the container | +| opencost.exporter.extraArgs | list | `[]` | List of extra arguments for the command, e.g.: log-format=json | +| opencost.exporter.extraEnv | object | `{}` | Any extra environment variables you would like to pass on to the pod | +| opencost.exporter.extraVolumeMounts | list | `[]` | A list of volume mounts to be added to the pod | +| opencost.exporter.image.fullImageName | string | `nil` | Override the full image name for development purposes | +| opencost.exporter.image.pullPolicy | string | `"IfNotPresent"` | Exporter container image pull policy | +| opencost.exporter.image.registry | string | `"ghcr.io"` | Exporter container image registry | +| opencost.exporter.image.repository | string | `"opencost/opencost"` | Exporter container image name | +| opencost.exporter.image.tag | string | `"1.111.0@sha256:6aa68e52a24b14ba41f23db08d1b9db1429a1c0300f4c0381ecc2c61fc311a97"` | Exporter container image tag | +| opencost.exporter.livenessProbe.enabled | bool | `true` | Whether probe is enabled | +| opencost.exporter.livenessProbe.failureThreshold | int | `3` | Number of failures for probe to be considered failed | +| opencost.exporter.livenessProbe.initialDelaySeconds | int | `10` | Number of seconds before probe is initiated | +| opencost.exporter.livenessProbe.path | string | `"/healthz"` | Probe path | +| opencost.exporter.livenessProbe.periodSeconds | int | `20` | Probe frequency in seconds | +| opencost.exporter.persistence.accessMode | string | `""` | Access mode for persistent volume | +| opencost.exporter.persistence.annotations | object | `{}` | Annotations for persistent volume | +| opencost.exporter.persistence.enabled | bool | `false` | | +| opencost.exporter.persistence.size | string | `""` | Size for persistent volume | +| opencost.exporter.persistence.storageClass | string | `""` | Storage class for persistent volume | +| opencost.exporter.readinessProbe.enabled | bool | `true` | Whether probe is enabled | +| opencost.exporter.readinessProbe.failureThreshold | int | `3` | Number of failures for probe to be considered failed | +| opencost.exporter.readinessProbe.initialDelaySeconds | int | `10` | Number of seconds before probe is initiated | +| opencost.exporter.readinessProbe.path | string | `"/healthz"` | Probe path | +| opencost.exporter.readinessProbe.periodSeconds | int | `10` | Probe frequency in seconds | +| opencost.exporter.replicas | int | `1` | Number of OpenCost replicas to run | +| opencost.exporter.resources.limits | object | `{"cpu":"999m","memory":"1Gi"}` | CPU/Memory resource limits | +| opencost.exporter.resources.requests | object | `{"cpu":"10m","memory":"55Mi"}` | CPU/Memory resource requests | +| opencost.exporter.securityContext | object | `{}` | The security options the container should be run with | +| opencost.exporter.startupProbe.enabled | bool | `true` | Whether probe is enabled | +| opencost.exporter.startupProbe.failureThreshold | int | `30` | Number of failures for probe to be considered failed | +| opencost.exporter.startupProbe.initialDelaySeconds | int | `10` | Number of seconds before probe is initiated | +| opencost.exporter.startupProbe.path | string | `"/healthz"` | Probe path | +| opencost.exporter.startupProbe.periodSeconds | int | `5` | Probe frequency in seconds | +| opencost.extraContainers | list | `[]` | extra sidecars to add to the pod. Useful for things like oauth-proxy for the UI | +| opencost.metrics.config.configmapName | string | `"custom-metrics"` | Customize the configmap name used for metrics | +| opencost.metrics.config.disabledMetrics | list | `[]` | List of metrics to be disabled | +| opencost.metrics.config.enabled | bool | `false` | Enables creating the metrics.json configuration as a ConfigMap | +| opencost.metrics.kubeStateMetrics.emitKsmV1Metrics | bool | `nil` | Enable emission of KSM v1 metrics | +| opencost.metrics.kubeStateMetrics.emitKsmV1MetricsOnly | bool | `nil` | Enable only emission of KSM v1 metrics that do not exist in KSM 2 by default | +| opencost.metrics.kubeStateMetrics.emitNamespaceAnnotations | bool | `nil` | Enable emission of namespace annotations | +| opencost.metrics.kubeStateMetrics.emitPodAnnotations | bool | `nil` | Enable emission of pod annotations | +| opencost.metrics.serviceMonitor.additionalLabels | object | `{}` | Additional labels to add to the ServiceMonitor | +| opencost.metrics.serviceMonitor.enabled | bool | `false` | Create ServiceMonitor resource for scraping metrics using PrometheusOperator | +| opencost.metrics.serviceMonitor.extraEndpoints | list | `[]` | extra Endpoints to add to the ServiceMonitor. Useful for scraping sidecars | +| opencost.metrics.serviceMonitor.honorLabels | bool | `true` | HonorLabels chooses the metric's labels on collisions with target labels | +| opencost.metrics.serviceMonitor.metricRelabelings | list | `[]` | MetricRelabelConfigs to apply to samples before ingestion | +| opencost.metrics.serviceMonitor.namespace | string | `""` | Specify if the ServiceMonitor will be deployed into a different namespace (blank deploys into same namespace as chart) | +| opencost.metrics.serviceMonitor.relabelings | list | `[]` | RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields | +| opencost.metrics.serviceMonitor.scheme | string | `"http"` | HTTP scheme used for scraping. Defaults to `http` | +| opencost.metrics.serviceMonitor.scrapeInterval | string | `"30s"` | Interval at which metrics should be scraped | +| opencost.metrics.serviceMonitor.scrapeTimeout | string | `"10s"` | Timeout after which the scrape is ended | +| opencost.metrics.serviceMonitor.tlsConfig | object | `{}` | TLS configuration for scraping metrics | +| opencost.nodeSelector | object | `{}` | Node labels for pod assignment | +| opencost.prometheus.amp.enabled | bool | `false` | Use Amazon Managed Service for Prometheus (AMP) | +| opencost.prometheus.amp.workspaceId | string | `""` | Workspace ID for AMP | +| opencost.prometheus.bearer_token | string | `""` | Prometheus Bearer token | +| opencost.prometheus.bearer_token_key | string | `"DB_BEARER_TOKEN"` | | +| opencost.prometheus.existingSecretName | string | `nil` | Existing secret name that contains credentials for Prometheus | +| opencost.prometheus.external.enabled | bool | `false` | Use external Prometheus (eg. Grafana Cloud) | +| opencost.prometheus.external.url | string | `"https://prometheus.example.com/prometheus"` | External Prometheus url | +| opencost.prometheus.internal.enabled | bool | `true` | Use in-cluster Prometheus | +| opencost.prometheus.internal.namespaceName | string | `"prometheus-system"` | Namespace of in-cluster Prometheus | +| opencost.prometheus.internal.port | int | `80` | Service port of in-cluster Prometheus | +| opencost.prometheus.internal.serviceName | string | `"prometheus-server"` | Service name of in-cluster Prometheus | +| opencost.prometheus.password | string | `""` | Prometheus Basic auth password | +| opencost.prometheus.password_key | string | `"DB_BASIC_AUTH_PW"` | Key in the secret that references the password | +| opencost.prometheus.secret_name | string | `nil` | Secret name that contains credentials for Prometheus | +| opencost.prometheus.thanos.enabled | bool | `false` | | +| opencost.prometheus.thanos.external.enabled | bool | `false` | | +| opencost.prometheus.thanos.external.url | string | `"https://thanos-query.example.com/thanos"` | | +| opencost.prometheus.thanos.internal.enabled | bool | `true` | | +| opencost.prometheus.thanos.internal.namespaceName | string | `"opencost"` | | +| opencost.prometheus.thanos.internal.port | int | `10901` | | +| opencost.prometheus.thanos.internal.serviceName | string | `"my-thanos-query"` | | +| opencost.prometheus.thanos.maxSourceResolution | string | `""` | | +| opencost.prometheus.thanos.queryOffset | string | `""` | | +| opencost.prometheus.username | string | `""` | Prometheus Basic auth username | +| opencost.prometheus.username_key | string | `"DB_BASIC_AUTH_USERNAME"` | Key in the secret that references the username | +| opencost.sigV4Proxy.extraEnv | string | `nil` | | +| opencost.sigV4Proxy.host | string | `"aps-workspaces.us-west-2.amazonaws.com"` | | +| opencost.sigV4Proxy.image | string | `"public.ecr.aws/aws-observability/aws-sigv4-proxy:latest"` | | +| opencost.sigV4Proxy.imagePullPolicy | string | `"IfNotPresent"` | | +| opencost.sigV4Proxy.name | string | `"aps"` | | +| opencost.sigV4Proxy.port | int | `8005` | | +| opencost.sigV4Proxy.region | string | `"us-west-2"` | | +| opencost.sigV4Proxy.resources | object | `{}` | | +| opencost.sigV4Proxy.securityContext | object | `{}` | | +| opencost.tolerations | list | `[]` | Toleration labels for pod assignment | +| opencost.topologySpreadConstraints | list | `[]` | Assign custom TopologySpreadConstraints rules | +| opencost.ui.enabled | bool | `true` | Enable OpenCost UI | +| opencost.ui.extraEnv | list | `[]` | A list of environment variables to be added to the pod | +| opencost.ui.extraVolumeMounts | list | `[]` | A list of volume mounts to be added to the pod | +| opencost.ui.image.fullImageName | string | `nil` | Override the full image name for development purposes | +| opencost.ui.image.pullPolicy | string | `"IfNotPresent"` | UI container image pull policy | +| opencost.ui.image.registry | string | `"ghcr.io"` | UI container image registry | +| opencost.ui.image.repository | string | `"opencost/opencost-ui"` | UI container image name | +| opencost.ui.image.tag | string | `""` (use appVersion in Chart.yaml) | UI container image tag | +| opencost.ui.ingress.annotations | object | `{}` | Annotations for Ingress resource | +| opencost.ui.ingress.enabled | bool | `false` | Ingress for OpenCost UI | +| opencost.ui.ingress.hosts | list | See [values.yaml](values.yaml) | A list of host rules used to configure the Ingress | +| opencost.ui.ingress.ingressClassName | string | `""` | Ingress controller which implements the resource | +| opencost.ui.ingress.servicePort | string | `"http-ui"` | Redirect ingress to an extraPort defined on the service such as oauth-proxy | +| opencost.ui.ingress.tls | list | `[]` | Ingress TLS configuration | +| opencost.ui.livenessProbe.enabled | bool | `true` | Whether probe is enabled | +| opencost.ui.livenessProbe.failureThreshold | int | `3` | Number of failures for probe to be considered failed | +| opencost.ui.livenessProbe.initialDelaySeconds | int | `30` | Number of seconds before probe is initiated | +| opencost.ui.livenessProbe.path | string | `"/healthz"` | Probe path | +| opencost.ui.livenessProbe.periodSeconds | int | `10` | Probe frequency in seconds | +| opencost.ui.readinessProbe.enabled | bool | `true` | Whether probe is enabled | +| opencost.ui.readinessProbe.failureThreshold | int | `3` | Number of failures for probe to be considered failed | +| opencost.ui.readinessProbe.initialDelaySeconds | int | `30` | Number of seconds before probe is initiated | +| opencost.ui.readinessProbe.path | string | `"/healthz"` | Probe path | +| opencost.ui.readinessProbe.periodSeconds | int | `10` | Probe frequency in seconds | +| opencost.ui.resources.limits | object | `{"cpu":"999m","memory":"1Gi"}` | CPU/Memory resource limits | +| opencost.ui.resources.requests | object | `{"cpu":"10m","memory":"55Mi"}` | CPU/Memory resource requests | +| opencost.ui.securityContext | object | `{}` | The security options the container should be run with | +| opencost.ui.uiPort | int | `9090` | | +| plugins.configs | string | `nil` | | +| plugins.enabled | bool | `false` | | +| plugins.folder | string | `"/opt/opencost/plugin"` | | +| plugins.install.enabled | bool | `true` | | +| plugins.install.fullImageName | string | `"curlimages/curl:latest"` | | +| plugins.install.securityContext.allowPrivilegeEscalation | bool | `false` | | +| plugins.install.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| plugins.install.securityContext.readOnlyRootFilesystem | bool | `true` | | +| plugins.install.securityContext.runAsNonRoot | bool | `true` | | +| plugins.install.securityContext.runAsUser | int | `1000` | | +| plugins.install.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| podAnnotations | object | `{}` | Annotations to add to the OpenCost Pod | +| podLabels | object | `{}` | Labels to add to the OpenCost Pod | +| podSecurityContext | object | `{}` | Holds pod-level security attributes and common container settings | +| priorityClassName | string | `nil` | Pod priority | +| rbac.enabled | bool | `true` | | +| secretAnnotations | object | `{}` | Annotations to add to the Secret | +| service.annotations | object | `{}` | Annotations to add to the service | +| service.enabled | bool | `true` | | +| service.extraPorts | list | `[]` | extra ports. Useful for sidecar pods such as oauth-proxy | +| service.labels | object | `{}` | Labels to add to the service account | +| service.loadBalancerSourceRanges | list | `[]` | LoadBalancer Source IP CIDR if service type is LoadBalancer and cloud provider supports this | +| service.nodePort | object | `{}` | NodePort if service type is NodePort | +| service.type | string | `"ClusterIP"` | Kubernetes Service type | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.automountServiceAccountToken | bool | `true` | Whether pods running as this service account should have an API token automatically mounted | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | | +| updateStrategy | object | `{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1},"type":"RollingUpdate"}` | Strategy to be used for the Deployment | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/packages/system/opencost/charts/opencost/README.md.gotmpl b/packages/system/opencost/charts/opencost/README.md.gotmpl new file mode 100644 index 00000000..70e24118 --- /dev/null +++ b/packages/system/opencost/charts/opencost/README.md.gotmpl @@ -0,0 +1,26 @@ +{{ template "chart.header" . }} + +{{ template "chart.description" . }} + +{{ template "chart.versionBadge" . }} +{{ template "chart.typeBadge" . }} +{{ template "chart.appVersionBadge" . }} +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/opencost)](https://artifacthub.io/packages/search?repo=opencost) +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/opencost-oci)](https://artifacthub.io/packages/search?repo=opencost-oci) + + +{{ template "chart.maintainersSection" . }} + +## Installing the Chart + +To install the chart with the release name `opencost`: + +```console +$ helm install opencost opencost/{{ template "chart.name" . }} +``` + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/packages/system/opencost/charts/opencost/templates/_helpers.tpl b/packages/system/opencost/charts/opencost/templates/_helpers.tpl new file mode 100644 index 00000000..ec38d3df --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/_helpers.tpl @@ -0,0 +1,182 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "opencost.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "opencost.chart" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | 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). +*/}} +{{- define "opencost.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 -}} + +{{/* +Allow the release namespace to be overridden +*/}} +{{- define "opencost.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- 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). +*/}} +{{- define "opencost.prometheus.secretname" -}} + {{- if .Values.opencost.prometheus.secret_name -}} + {{- .Values.opencost.prometheus.secret_name -}} + {{- else -}} + {{- include "opencost.fullname" . -}} + {{- end -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "opencost.labels" -}} +helm.sh/chart: {{ include "opencost.chart" . }} +{{ include "opencost.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/part-of: {{ template "opencost.name" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.commonLabels}} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "opencost.selectorLabels" -}} +app.kubernetes.io/name: {{ include "opencost.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the controller service account to use +*/}} +{{- define "opencost.serviceAccountName" -}} + {{- if .Values.serviceAccount.create -}} + {{- default (include "opencost.fullname" .) .Values.serviceAccount.name }} + {{- else -}} + {{- default "default" .Values.serviceAccount.name }} + {{- end -}} +{{- end -}} + +{{/* +Create the name of the controller service account to use +*/}} +{{- define "opencost.prometheusServerEndpoint" -}} + {{- if .Values.opencost.prometheus.external.enabled -}} + {{ tpl .Values.opencost.prometheus.external.url . }} + {{- else if (and .Values.opencost.prometheus.amp.enabled .Values.opencost.sigV4Proxy) -}} + {{- $port := .Values.opencost.sigV4Proxy.port | int }} + {{- $ws := .Values.opencost.prometheus.amp.workspaceId }} + {{- printf "http://localhost:%d/workspaces/%v" $port $ws -}} + {{- else -}} + {{- $host := tpl .Values.opencost.prometheus.internal.serviceName . }} + {{- $ns := tpl .Values.opencost.prometheus.internal.namespaceName . }} + {{- $port := .Values.opencost.prometheus.internal.port | int }} + {{- printf "http://%s.%s.svc.cluster.local:%d" $host $ns $port -}} + {{- end -}} +{{- end -}} + +{{/* +Check that either thanos external or internal is defined +*/}} +{{- define "opencost.thanosServerEndpoint" -}} + {{- if .Values.opencost.prometheus.thanos.external.enabled -}} + {{ .Values.opencost.prometheus.thanos.external.url }} + {{- else -}} + {{- $host := .Values.opencost.prometheus.thanos.internal.serviceName }} + {{- $ns := .Values.opencost.prometheus.thanos.internal.namespaceName }} + {{- $port := .Values.opencost.prometheus.thanos.internal.port | int }} + {{- printf "http://%s.%s.svc.cluster.local:%d" $host $ns $port -}} + {{- end -}} +{{- end -}} + +{{/* +Check that the config is valid +*/}} +{{- define "isPrometheusConfigValid" -}} + {{- $prometheusModes := add .Values.opencost.prometheus.external.enabled .Values.opencost.prometheus.internal.enabled .Values.opencost.prometheus.amp.enabled | int }} + {{- if gt $prometheusModes 1 -}} + {{- fail "Only use one of the prometheus setups: internal, external, or amp" -}} + {{- end -}} + {{- if .Values.opencost.prometheus.thanos.enabled -}} + {{- if and .Values.opencost.prometheus.thanos.external.enabled .Values.opencost.prometheus.thanos.internal.enabled -}} + {{- fail "Only use one of the thanos setups: internal or external" -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Define opencost config file name +*/}} +{{- define "opencost.configFileName" -}} + {{- if eq .Values.opencost.customPricing.provider "custom" -}} + {{- print "default" -}} + {{- else -}} + {{- .Values.opencost.customPricing.provider -}} + {{- end -}} +{{- end -}} + +{{/* +Get api version of networking.k8s.io +*/}} +{{- define "networkingAPIVersion" -}} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} +apiVersion: networking.k8s.io/v1 +{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +apiVersion: networking.k8s.io/v1beta1 +{{- end }} +{{- end -}} + +{{- define "opencost.imageTag" -}} +{{ .Values.opencost.exporter.image.tag | default (printf "%s" .Chart.AppVersion) }} +{{- end -}} + +{{- define "opencost.fullImageName" -}} +{{- if .Values.opencost.exporter.image.fullImageName }} +{{- .Values.opencost.exporter.image.fullImageName -}} +{{- else}} +{{- .Values.opencost.exporter.image.registry -}}/{{- .Values.opencost.exporter.image.repository -}}:{{- include "opencost.imageTag" . -}} +{{- end -}} +{{- end -}} + +{{- define "opencostUi.imageTag" -}} +{{- .Values.opencost.ui.image.tag | default (printf "%s" .Chart.AppVersion) -}} +{{- end -}} + +{{- define "opencostUi.fullImageName" -}} +{{- if .Values.opencost.ui.image.fullImageName }} +{{- .Values.opencost.ui.image.fullImageName -}} +{{- else}} +{{- .Values.opencost.ui.image.registry -}}/{{- .Values.opencost.ui.image.repository -}}:{{- include "opencostUi.imageTag" . -}} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/packages/system/opencost/charts/opencost/templates/clusterrole.yaml b/packages/system/opencost/charts/opencost/templates/clusterrole.yaml new file mode 100644 index 00000000..f033a036 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/clusterrole.yaml @@ -0,0 +1,79 @@ +# Cluster role giving opencost to get, list, watch required resources +# No write permissions are required +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "opencost.fullname" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: + - configmaps + - deployments + - nodes + - pods + - services + - resourcequotas + - replicationcontrollers + - limitranges + - persistentvolumeclaims + - persistentvolumes + - namespaces + - endpoints + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - daemonsets + - deployments + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - deployments + - daemonsets + - replicasets + verbs: + - list + - watch + - apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch + - apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch diff --git a/packages/system/opencost/charts/opencost/templates/clusterrolebinding.yaml b/packages/system/opencost/charts/opencost/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..56f4e00b --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/clusterrolebinding.yaml @@ -0,0 +1,18 @@ +{{- if .Values.rbac.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "opencost.fullname" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "opencost.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "opencost.serviceAccountName" . }} + namespace: {{ include "opencost.namespace" . }} +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/configmap-custom-pricing.yaml b/packages/system/opencost/charts/opencost/templates/configmap-custom-pricing.yaml new file mode 100644 index 00000000..d7497379 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/configmap-custom-pricing.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.opencost.customPricing.createConfigmap .Values.opencost.customPricing.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.opencost.customPricing.configmapName }} + namespace: {{ include "opencost.namespace" . }} +data: + {{ include "opencost.configFileName" . }}.json: |- + { +{{- range $key, $val := .Values.opencost.customPricing.costModel }} +{{ $key | quote | indent 6}}: {{ $val | quote }}, +{{- end}} + "provider" : {{ .Values.opencost.customPricing.provider | quote }} + } +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/configmap-metrics-config.yaml b/packages/system/opencost/charts/opencost/templates/configmap-metrics-config.yaml new file mode 100644 index 00000000..f4be7a2e --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/configmap-metrics-config.yaml @@ -0,0 +1,11 @@ +{{- if .Values.opencost.metrics.config.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.opencost.metrics.config.configmapName }} + namespace: {{ include "opencost.namespace" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} +data: + metrics.json: |- + {"disabledMetrics": {{ toJson .Values.opencost.metrics.config.disabledMetrics }} } +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/deployment.yaml b/packages/system/opencost/charts/opencost/templates/deployment.yaml new file mode 100644 index 00000000..1d8e2912 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/deployment.yaml @@ -0,0 +1,390 @@ +{{- include "isPrometheusConfigValid" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "opencost.fullname" . }} + namespace: {{ include "opencost.namespace" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.opencost.exporter.replicas }} + selector: + matchLabels: {{- include "opencost.selectorLabels" . | nindent 6 }} + strategy: {{ toYaml .Values.updateStrategy | nindent 4 }} + template: + metadata: + labels: + {{- include "opencost.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podAnnotations }} + annotations: {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "opencost.serviceAccountName" . }} + {{- with .Values.opencost.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.opencost.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.opencost.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with.Values.opencost.topologySpreadConstraints }} + topologySpreadConstraints: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if (and .Values.plugins.enabled .Values.plugins.install.enabled )}} + initContainers: + - name: plugin-installer + image: {{ .Values.plugins.install.fullImageName }} + command: ["sh", "/install/install_plugins.sh"] + {{- with .Values.plugins.install.securityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: install-script + mountPath: /install + - name: plugins-dir + mountPath: {{ .Values.plugins.folder }} + {{- end }} + containers: + - name: {{ include "opencost.fullname" . }} + image: {{ include "opencost.fullImageName" . }} + imagePullPolicy: {{ .Values.opencost.exporter.image.pullPolicy }} + args: + {{- range .Values.opencost.exporter.extraArgs }} + - --{{ . }} + {{- end }} + ports: + - containerPort: {{ .Values.opencost.exporter.apiPort }} + name: http + resources: {{- toYaml .Values.opencost.exporter.resources | nindent 12 }} + {{- if .Values.opencost.exporter.startupProbe.enabled }} + startupProbe: + httpGet: + path: {{ .Values.opencost.exporter.startupProbe.path }} + port: {{ .Values.opencost.exporter.apiPort }} + initialDelaySeconds: {{ .Values.opencost.exporter.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.opencost.exporter.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.opencost.exporter.startupProbe.failureThreshold }} + {{- end }} + {{- if .Values.opencost.exporter.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.opencost.exporter.livenessProbe.path }} + port: {{ .Values.opencost.exporter.apiPort }} + initialDelaySeconds: {{ .Values.opencost.exporter.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.opencost.exporter.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.opencost.exporter.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.opencost.exporter.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.opencost.exporter.readinessProbe.path }} + port: {{ .Values.opencost.exporter.apiPort }} + initialDelaySeconds: {{ .Values.opencost.exporter.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.opencost.exporter.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.opencost.exporter.readinessProbe.failureThreshold }} + {{- end }} + {{- with .Values.opencost.exporter.securityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: LOG_LEVEL + value: {{ .Values.loglevel }} + - name: CUSTOM_COST_ENABLED + value: {{ .Values.plugins.enabled | quote }} + - name: KUBECOST_NAMESPACE + value: {{ include "opencost.namespace" . }} + {{- if .Values.opencost.metrics.config.enabled }} + - name: METRICS_CONFIGMAP_NAME + value: {{ .Values.opencost.metrics.config.configmapName }} + {{- end }} + {{- if .Values.opencost.exporter.apiPort }} + - name: API_PORT + value: {{ .Values.opencost.exporter.apiPort | quote }} + {{- end }} + {{- if .Values.opencost.carbonCost.enabled }} + - name: CARBON_ESTIMATES_ENABLED + value: {{ .Values.opencost.carbonCost.enabled | quote }} + {{- end }} + - name: PROMETHEUS_SERVER_ENDPOINT + value: {{ include "opencost.prometheusServerEndpoint" . | quote }} + {{- if .Values.opencost.exporter.cloudProviderApiKey }} + - name: CLOUD_PROVIDER_API_KEY + valueFrom: + secretKeyRef: + name: {{ include "opencost.prometheus.secretname" . }} + key: CLOUD_PROVIDER_API_KEY + {{- end }} + - name: CLUSTER_ID + value: {{ .Values.opencost.exporter.defaultClusterId | quote }} + {{- if .Values.opencost.exporter.aws.access_key_id }} + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: {{ include "opencost.prometheus.secretname" . }} + key: AWS_ACCESS_KEY_ID + {{- end }} + {{- if .Values.opencost.exporter.aws.secret_access_key }} + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: {{ include "opencost.prometheus.secretname" . }} + key: AWS_SECRET_ACCESS_KEY + {{- end }} + {{- if and .Values.opencost.prometheus.username_key (or .Values.opencost.prometheus.username .Values.opencost.prometheus.existingSecretName) }} + - name: DB_BASIC_AUTH_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.opencost.prometheus.existingSecretName | default (include "opencost.prometheus.secretname" .) }} + key: {{ .Values.opencost.prometheus.username_key }} + {{- end }} + {{- if and .Values.opencost.prometheus.password_key (or .Values.opencost.prometheus.password .Values.opencost.prometheus.existingSecretName) }} + - name: DB_BASIC_AUTH_PW + valueFrom: + secretKeyRef: + name: {{ .Values.opencost.prometheus.existingSecretName | default (include "opencost.prometheus.secretname" .) }} + key: {{ .Values.opencost.prometheus.password_key }} + {{- else if and .Values.opencost.prometheus.bearer_token_key (or .Values.opencost.prometheus.bearer_token .Values.opencost.prometheus.existingSecretName) }} + - name: DB_BEARER_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.opencost.prometheus.existingSecretName | default (include "opencost.prometheus.secretname" .) }} + key: {{ .Values.opencost.prometheus.bearer_token_key }} + {{- end }} + {{- if and .Values.opencost.exporter.persistence.enabled .Values.opencost.exporter.csv_path }} + - name: EXPORT_CSV_FILE + value: {{ .Values.opencost.exporter.csv_path | quote }} + {{- end }} + {{- if .Values.opencost.prometheus.thanos.enabled }} + - name: THANOS_ENABLED + value: 'true' + - name: THANOS_QUERY_URL + value: {{ include "opencost.thanosServerEndpoint" . | quote }} + {{- end }} + {{- if .Values.opencost.prometheus.thanos.queryOffset }} + - name: THANOS_QUERY_OFFSET + value: {{ .Values.opencost.prometheus.thanos.queryOffset | quote }} + {{- end }} + {{- if .Values.opencost.prometheus.thanos.maxSourceResolution }} + - name: THANOS_MAX_SOURCE_RESOLUTION + value: {{ .Values.opencost.prometheus.thanos.maxSourceResolution | quote }} + {{- end }} + {{- with .Values.opencost.exporter.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.opencost.customPricing.enabled }} + - name: CONFIG_PATH + value: {{ .Values.opencost.customPricing.configPath | quote }} + {{- end }} + - name: DATA_RETENTION_DAILY_RESOLUTION_DAYS + value: {{ .Values.opencost.dataRetention.dailyResolutionDays | quote }} + - name: CLOUD_COST_ENABLED + value: {{ .Values.opencost.cloudCost.enabled | quote }} + - name: CLOUD_COST_MONTH_TO_DATE_INTERVAL + value: {{ .Values.opencost.cloudCost.monthToDateInterval | quote }} + - name: CLOUD_COST_REFRESH_RATE_HOURS + value: {{ .Values.opencost.cloudCost.refreshRateHours | quote }} + - name: CLOUD_COST_QUERY_WINDOW_DAYS + value: {{ .Values.opencost.cloudCost.queryWindowDays | quote }} + - name: CLOUD_COST_RUN_WINDOW_DAYS + value: {{ .Values.opencost.cloudCost.runWindowDays | quote }} + {{- if not (quote .Values.opencost.metrics.kubeStateMetrics.emitPodAnnotations | empty ) }} + - name: EMIT_POD_ANNOTATIONS_METRIC + value: {{ .Values.opencost.metrics.kubeStateMetrics.emitPodAnnotations | quote }} + {{- end }} + {{- if not (quote .Values.opencost.metrics.kubeStateMetrics.emitNamespaceAnnotations | empty ) }} + - name: EMIT_NAMESPACE_ANNOTATIONS_METRIC + value: {{ .Values.opencost.metrics.kubeStateMetrics.emitNamespaceAnnotations | quote }} + {{- end }} + {{- if not (quote .Values.opencost.metrics.kubeStateMetrics.emitKsmV1Metrics | empty ) }} + - name: EMIT_KSM_V1_METRICS + value: {{ .Values.opencost.metrics.kubeStateMetrics.emitKsmV1Metrics | quote }} + {{- end }} + {{- if not (quote .Values.opencost.metrics.kubeStateMetrics.emitKsmV1MetricsOnly | empty ) }} + - name: EMIT_KSM_V1_METRICS_ONLY + value: {{ .Values.opencost.metrics.kubeStateMetrics.emitKsmV1MetricsOnly | quote }} + {{- end }} + # Add any additional provided variables + {{- range $key, $value := .Values.opencost.exporter.extraEnv }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- if or .Values.plugins.enabled .Values.opencost.exporter.persistence.enabled .Values.opencost.exporter.extraVolumeMounts .Values.opencost.customPricing.enabled .Values.opencost.cloudIntegrationSecret}} + volumeMounts: + {{- if .Values.plugins.enabled }} + - mountPath: /opt/opencost/plugin + name: plugins-dir + readOnly: false + {{- range $key, $config := .Values.plugins.configs }} + - mountPath: /opt/opencost/plugin/config/{{$key}}_config.json + subPath: {{$key}}_config.json + name: plugins-config + readOnly: true + {{- end }} + {{- end }} + {{- if .Values.opencost.exporter.persistence.enabled }} + - mountPath: /mnt/export + name: opencost-export + readOnly: false + {{- end }} + {{- if .Values.opencost.customPricing.enabled }} + - mountPath: {{ .Values.opencost.customPricing.configPath }}/{{ include "opencost.configFileName" . }}.json + name: custom-configs + subPath: {{ include "opencost.configFileName" . }}.json + readOnly: true + {{- end }} + {{- if .Values.opencost.metrics.config.enabled }} + - mountPath: {{ .Values.opencost.customPricing.configPath }}/metrics.json + name: custom-metrics + subPath: metrics.json + readOnly: true + {{- end }} + {{- if .Values.opencost.cloudIntegrationSecret }} + - name: cloud-integration + mountPath: /var/configs/cloud-integration + {{- end }} + {{- with .Values.opencost.exporter.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.opencost.ui.enabled }} + - name: opencost-ui + image: {{ include "opencostUi.fullImageName" .}} + imagePullPolicy: {{ .Values.opencost.ui.image.pullPolicy }} + ports: + - containerPort: {{ .Values.opencost.ui.uiPort }} + name: http-ui + env: + {{- with .Values.opencost.ui.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.opencost.ui.apiServer }} + - name: API_SERVER + value: {{ .Values.opencost.ui.apiServer | quote }} + {{- end }} + {{- if .Values.opencost.exporter.apiPort }} + - name: API_PORT + value: {{ .Values.opencost.exporter.apiPort | quote }} + {{- end }} + {{- if .Values.opencost.ui.uiPort }} + - name: UI_PORT + value: {{ .Values.opencost.ui.uiPort | quote }} + {{- end }} + resources: {{- toYaml .Values.opencost.ui.resources | nindent 12 }} + {{- if .Values.opencost.ui.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.opencost.ui.livenessProbe.path }} + port: {{ .Values.opencost.ui.uiPort }} + initialDelaySeconds: {{ .Values.opencost.ui.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.opencost.ui.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.opencost.ui.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.opencost.ui.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.opencost.ui.readinessProbe.path }} + port: {{ .Values.opencost.ui.uiPort }} + initialDelaySeconds: {{ .Values.opencost.ui.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.opencost.ui.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.opencost.ui.readinessProbe.failureThreshold }} + {{- end }} + {{- with .Values.opencost.ui.securityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.opencost.ui.extraVolumeMounts }} + volumeMounts: {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- with .Values.opencost.extraContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if and .Values.opencost.prometheus.amp.enabled .Values.opencost.sigV4Proxy }} + - name: sigv4proxy + image: {{ .Values.opencost.sigV4Proxy.image }} + imagePullPolicy: {{ .Values.opencost.sigV4Proxy.imagePullPolicy }} + args: + - --name + - {{ .Values.opencost.sigV4Proxy.name }} + - --region + - {{ .Values.opencost.sigV4Proxy.region }} + - --host + - {{ .Values.opencost.sigV4Proxy.host }} + {{- if .Values.opencost.sigV4Proxy.role_arn }} + - --role-arn + - {{ .Values.opencost.sigV4Proxy.role_arn }} + {{- end }} + - --port + - :{{ .Values.opencost.sigV4Proxy.port }} + ports: + - name: aws-sigv4-proxy + containerPort: {{ .Values.opencost.sigV4Proxy.port | int }} + {{- with .Values.opencost.sigV4Proxy.extraEnv }} + env: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.opencost.sigV4Proxy.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.opencost.sigV4Proxy.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- if or .Values.plugins.enabled .Values.opencost.exporter.persistence.enabled .Values.extraVolumes .Values.opencost.customPricing.enabled .Values.opencost.cloudIntegrationSecret}} + volumes: + {{- if .Values.plugins.enabled }} + {{- if .Values.plugins.install.enabled}} + - name: install-script + configMap: + name: {{ template "opencost.fullname" . }}-install-plugins + {{- end }} + - name: plugins-dir + emptyDir: {} + - name: plugins-config + secret: + secretName: {{ template "opencost.fullname" . }}-plugins-config + {{- end }} + {{- if .Values.opencost.customPricing.enabled }} + - name: custom-configs + configMap: + name: {{ .Values.opencost.customPricing.configmapName }} + {{- end }} + {{- if .Values.opencost.metrics.config.enabled }} + - name: custom-metrics + configMap: + name: {{ .Values.opencost.metrics.config.configmapName }} + {{- end }} + {{- if .Values.opencost.exporter.persistence.enabled }} + - name: opencost-export + persistentVolumeClaim: + claimName: {{ include "opencost.fullname" . }}-pvc + {{- end }} + {{- if .Values.opencost.cloudIntegrationSecret }} + - name: cloud-integration + secret: + secretName: {{ .Values.opencost.cloudIntegrationSecret }} + items: + - key: cloud-integration.json + path: cloud-integration.json + {{- end }} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/ingress.yaml b/packages/system/opencost/charts/opencost/templates/ingress.yaml new file mode 100644 index 00000000..7973d12e --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/ingress.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.opencost.ui.enabled .Values.opencost.ui.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "opencost.fullname" . }}-ingress + namespace: {{ include "opencost.namespace" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} + {{- with .Values.opencost.ui.ingress.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.opencost.ui.ingress.ingressClassName }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.opencost.ui.ingress.tls }} + tls: + {{- range .Values.opencost.ui.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.opencost.ui.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ . }} + pathType: Prefix + backend: + service: + name: {{ include "opencost.fullname" $ }} + port: + name: {{ $.Values.opencost.ui.ingress.servicePort }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/packages/system/opencost/charts/opencost/templates/install-plugins.yaml b/packages/system/opencost/charts/opencost/templates/install-plugins.yaml new file mode 100644 index 00000000..31d7dbe1 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/install-plugins.yaml @@ -0,0 +1,46 @@ +{{- if .Values.plugins.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "opencost.fullname" . }}-install-plugins + labels: + app: {{ template "opencost.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + install_plugins.sh: |- + {{- if .Values.plugins.install.enabled }} + set -ex + rm -f {{ .Values.plugins.folder }}/bin/* + mkdir -p {{ .Values.plugins.folder }}/bin + cd {{ .Values.plugins.folder }}/bin + OSTYPE=$(cat /etc/os-release) + OS='' + case "$OSTYPE" in + *Linux*) OS='linux';; + *) echo "$OSTYPE is unsupported" && exit 1 ;; + esac + + UNAME_OUTPUT=$(uname -m) + ARCH='' + case "$UNAME_OUTPUT" in + *x86_64*) ARCH='amd64';; + *amd64*) ARCH='amd64';; + *aarch64*) ARCH='arm64';; + *arm64*) ARCH='arm64';; + *) echo "$UNAME_OUTPUT is unsupported" && exit 1 ;; + esac + + {{- if .Values.plugins.version }} + VER={{ .Values.plugins.version | quote}} + {{- else }} + VER=$(curl --silent https://api.github.com/repos/opencost/opencost-plugins/releases/latest | grep ".tag_name" | awk -F\" '{print $4}') + {{- end }} + + {{- range $pluginName, $config := .Values.plugins.configs }} + curl -fsSLO "https://github.com/opencost/opencost-plugins/releases/download/$VER/{{ $pluginName }}.ocplugin.$OS.$ARCH" + chmod a+rx "{{ $pluginName }}.ocplugin.$OS.$ARCH" + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/packages/system/opencost/charts/opencost/templates/networkpolicy.yaml b/packages/system/opencost/charts/opencost/templates/networkpolicy.yaml new file mode 100644 index 00000000..a601f067 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/networkpolicy.yaml @@ -0,0 +1,49 @@ +{{- $apiVersion := (include "networkingAPIVersion" .) }} +{{- if .Values.networkPolicies.enabled -}} +{{- if .Values.opencost.prometheus.internal.enabled }} +--- +{{ $apiVersion }} +kind: NetworkPolicy +metadata: + name: {{ .Release.Name }}-opencost + namespace: {{ include "opencost.namespace" . }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: opencost + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + {{- range $key, $val := .Values.networkPolicies.prometheus.labels }} + {{ $key }}: {{ $val }} + {{- end }} + {{- if ne .Values.networkPolicies.prometheus.namespace .Release.Namespace }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Values.networkPolicies.prometheus.namespace }} + {{- end }} + ports: + - port: 9003 + egress: + - to: + - podSelector: + matchLabels: + {{- range $key, $val := .Values.networkPolicies.prometheus.labels }} + {{ $key }}: {{ $val }} + {{- end }} + {{- if ne .Values.networkPolicies.prometheus.namespace .Release.Namespace }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Values.networkPolicies.prometheus.namespace }} + {{- end }} + ports: + - port: {{ .Values.networkPolicies.prometheus.port }} + {{- if .Values.networkPolicies.extraEgress -}} + {{ toYaml .Values.networkPolicies.extraEgress | nindent 4 }} + {{- end -}} +{{- end }} +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/plugins-config.yaml b/packages/system/opencost/charts/opencost/templates/plugins-config.yaml new file mode 100644 index 00000000..2a6f0ac4 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/plugins-config.yaml @@ -0,0 +1,16 @@ +{{- if .Values.plugins.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "opencost.fullname" . }}-plugins-config + labels: + app: {{ template "opencost.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + {{- range $key, $config := .Values.plugins.configs }} + {{ $key }}_config.json: + {{ $config | b64enc | indent 4}} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/packages/system/opencost/charts/opencost/templates/pvc.yaml b/packages/system/opencost/charts/opencost/templates/pvc.yaml new file mode 100644 index 00000000..1295765b --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/pvc.yaml @@ -0,0 +1,18 @@ +{{- if .Values.opencost.exporter.persistence.enabled }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ include "opencost.fullname" . }}-pvc + namespace: {{ include "opencost.namespace" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} + {{- with .Values.opencost.exporter.persistence.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: + - {{ .Values.opencost.exporter.persistence.accessMode | quote }} + storageClassName: {{ default "" .Values.opencost.exporter.persistence.storageClass }} + resources: + requests: + storage: {{ .Values.opencost.exporter.persistence.size | quote }} +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/secret.yaml b/packages/system/opencost/charts/opencost/templates/secret.yaml new file mode 100644 index 00000000..214f6499 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/secret.yaml @@ -0,0 +1,30 @@ +{{- if or .Values.opencost.prometheus.username .Values.opencost.prometheus.password .Values.opencost.prometheus.bearer_token .Values.opencost.exporter.aws.access_key_id .Values.opencost.exporter.cloudProviderApiKey }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "opencost.prometheus.secretname" . }} + namespace: {{ include "opencost.namespace" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} + {{- with .Values.secretAnnotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +data: + {{- if .Values.opencost.prometheus.username }} + {{ .Values.opencost.prometheus.username_key }}: {{ .Values.opencost.prometheus.username | toString | b64enc | quote }} + {{- end }} + {{- if .Values.opencost.prometheus.password }} + {{ .Values.opencost.prometheus.password_key }}: {{ .Values.opencost.prometheus.password | toString | b64enc | quote }} + {{- end }} + {{- if .Values.opencost.prometheus.bearer_token }} + {{ .Values.opencost.prometheus.bearer_token_key }}: {{ .Values.opencost.prometheus.bearer_token | b64enc | quote }} + {{- end }} + {{- if .Values.opencost.exporter.aws.access_key_id }} + AWS_ACCESS_KEY_ID: {{ .Values.opencost.exporter.aws.access_key_id | b64enc | quote }} + {{- end }} + {{- if .Values.opencost.exporter.aws.access_key_id }} + AWS_SECRET_ACCESS_KEY: {{ .Values.opencost.exporter.aws.secret_access_key | b64enc | quote }} + {{- end }} + {{- if .Values.opencost.exporter.cloudProviderApiKey }} + CLOUD_PROVIDER_API_KEY: {{ .Values.opencost.exporter.cloudProviderApiKey | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/service.yaml b/packages/system/opencost/charts/opencost/templates/service.yaml new file mode 100644 index 00000000..4c8c8e5a --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/service.yaml @@ -0,0 +1,48 @@ +{{- if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "opencost.fullname" . }} + namespace: {{ include "opencost.namespace" . }} + labels: + {{- include "opencost.labels" . | nindent 4 }} + {{- with .Values.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.service.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: {{- include "opencost.selectorLabels" . | nindent 4 }} + {{- if and .Values.service .Values.service.type }} + type: "{{ .Values.service.type }}" + {{- end }} + {{- if (eq .Values.service.type "LoadBalancer") }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} + {{- end -}} + {{- end }} + ports: + - name: http + port: {{ .Values.opencost.exporter.apiPort }} + targetPort: {{ .Values.opencost.exporter.apiPort }} + {{- if .Values.opencost.ui.enabled }} + - name: http-ui + port: {{ .Values.opencost.ui.uiPort }} + targetPort: {{ .Values.opencost.ui.uiPort }} + {{- if (eq .Values.service.type "NodePort") }} + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.opencost.exporter.debugPort }} + - name: debug-port + port: {{ .Values.opencost.exporter.debugPort }} + targetPort: {{ .Values.opencost.debugPort }} + {{- end }} + {{- with .Values.service.extraPorts }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/serviceaccount.yaml b/packages/system/opencost/charts/opencost/templates/serviceaccount.yaml new file mode 100644 index 00000000..cdfe390f --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "opencost.serviceAccountName" . }} + namespace: {{ include "opencost.namespace" . }} + labels: {{- include "opencost.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/packages/system/opencost/charts/opencost/templates/servicemonitor.yaml b/packages/system/opencost/charts/opencost/templates/servicemonitor.yaml new file mode 100644 index 00000000..2998bb16 --- /dev/null +++ b/packages/system/opencost/charts/opencost/templates/servicemonitor.yaml @@ -0,0 +1,42 @@ +{{- if .Values.opencost.metrics.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "opencost.fullname" . }} + {{- if .Values.opencost.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.opencost.metrics.serviceMonitor.namespace | quote }} + {{- end }} + labels: + {{- include "opencost.labels" . | nindent 4 }} + {{- if .Values.opencost.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.opencost.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: http + scheme: {{ .Values.opencost.metrics.serviceMonitor.scheme }} + path: /metrics + interval: {{ .Values.opencost.metrics.serviceMonitor.scrapeInterval }} + scrapeTimeout: {{ .Values.opencost.metrics.serviceMonitor.scrapeTimeout }} + {{- if .Values.opencost.metrics.serviceMonitor.honorLabels }} + honorLabels: true + {{- end }} + {{- with .Values.opencost.metrics.serviceMonitor.relabelings }} + relabelings: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.opencost.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.opencost.metrics.serviceMonitor.extraEndpoints }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.opencost.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8}} + {{- end }} + selector: + matchLabels: {{- include "opencost.selectorLabels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} diff --git a/packages/system/opencost/charts/opencost/tests/deployment_test.yaml b/packages/system/opencost/charts/opencost/tests/deployment_test.yaml new file mode 100644 index 00000000..79cd0842 --- /dev/null +++ b/packages/system/opencost/charts/opencost/tests/deployment_test.yaml @@ -0,0 +1,16 @@ +suite: test deployment +templates: + - templates/deployment.yaml +tests: + - it: should work + set: + image.tag: latest + asserts: + - isKind: + of: Deployment + - matchRegex: + path: metadata.name + pattern: -opencost$ + - matchRegex: + path: spec.template.spec.containers[0].image + pattern: ghcr\.io\/opencost\/opencost:[0-9]*\.[0-9]*\.[0-9]* diff --git a/packages/system/opencost/charts/opencost/tests/opencost_test.yaml b/packages/system/opencost/charts/opencost/tests/opencost_test.yaml new file mode 100644 index 00000000..bd84e6a8 --- /dev/null +++ b/packages/system/opencost/charts/opencost/tests/opencost_test.yaml @@ -0,0 +1,7 @@ +suite: test deployment snapshot +templates: + - templates/deployment.yaml +tests: + - it: pod spec should match snapshot + asserts: + - matchSnapshot: {} diff --git a/packages/system/opencost/charts/opencost/tests/service_test.yaml b/packages/system/opencost/charts/opencost/tests/service_test.yaml new file mode 100644 index 00000000..b1fec3a8 --- /dev/null +++ b/packages/system/opencost/charts/opencost/tests/service_test.yaml @@ -0,0 +1,29 @@ +suite: test service +templates: + - templates/service.yaml +tests: + - it: should work + set: + service: + type: ClusterIP + asserts: + - equal: + path: spec.type + value: ClusterIP + - it: should render right if values given + set: + service: + type: NodePort + NodePort: 30200 + asserts: + - equal: + path: spec.type + value: NodePort + - it: should render right if values given + set: + service: + type: LoadBalancer + asserts: + - equal: + path: spec.type + value: LoadBalancer diff --git a/packages/system/opencost/charts/opencost/values.yaml b/packages/system/opencost/charts/opencost/values.yaml new file mode 100644 index 00000000..ed1ce776 --- /dev/null +++ b/packages/system/opencost/charts/opencost/values.yaml @@ -0,0 +1,512 @@ +# -- Overwrite the default name of the chart +nameOverride: "" +# -- Overwrite all resources name created by the chart +fullnameOverride: "" +# -- Override the deployment namespace +namespaceOverride: "" + +loglevel: info + +plugins: + enabled: false + install: + enabled: true + fullImageName: curlimages/curl:latest + securityContext: + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + folder: /opt/opencost/plugin + # leave this commented to always download most recent version of plugins + # version: + configs: + # datadog: | + # { + # "datadog_site": "", + # "datadog_api_key": "", + # "datadog_app_key": "" + # } + +# -- List of secret names to use for pulling the images +imagePullSecrets: [] + +serviceAccount: + # -- Specifies whether a service account should be created + create: true + # -- Annotations to add to the service account + annotations: {} + # eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/eksctl-opencost + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + # -- Whether pods running as this service account should have an API token automatically mounted + automountServiceAccountToken: true + +# NetworkPolicies for ingress +networkPolicies: + # -- Specifies whether networkpolicies should be created + enabled: false + + # -- Internal Prometheus settings related to NetworkPolicies + prometheus: + # -- Namespace where internal Prometheus is installed + namespace: prometheus-system + # -- Pod port of in-cluster Prometheus + port: 9090 + # -- Labels applied to the Prometheus server pod(s) + labels: + app.kubernetes.io/name: prometheus + + # -- Extra egress rule + extraEgress: [] + +# -- Strategy to be used for the Deployment +updateStrategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate +# -- Annotations to add to the all the resources +annotations: {} +# -- Annotations to add to the OpenCost Pod +podAnnotations: {} +# -- Annotations to add to the Secret +secretAnnotations: {} +# -- Labels to add to the OpenCost Pod +podLabels: {} +# -- Pod priority +priorityClassName: ~ + +# -- Holds pod-level security attributes and common container settings +podSecurityContext: {} + # fsGroup: 2000 + +service: + enabled: true + # -- Annotations to add to the service + annotations: {} + # -- Labels to add to the service account + labels: {} + # -- Kubernetes Service type + type: ClusterIP + # -- NodePort if service type is NodePort + nodePort: {} + # -- extra ports. Useful for sidecar pods such as oauth-proxy + extraPorts: [] + # - name: oauth-proxy + # port: 8081 + # targetPort: 8081 + # - name: oauth-metrics + # port: 8082 + # targetPort: 8082 + # -- LoadBalancer Source IP CIDR if service type is LoadBalancer and cloud provider supports this + loadBalancerSourceRanges: [] + +# Create cluster role policies +rbac: + enabled: true + +opencost: + # -- for the secret containing the Cloud Costs cloud-integration.json https://www.opencost.io/docs/configuration/#cloud-costs + # -- kubectl create secret generic --from-file=cloud-integration.json -n opencost + cloudIntegrationSecret: "" + exporter: + # API_PORT for the cost-model to listen on + apiPort: 9003 + # debugPort: 40000 # for development purposes (debugging with delve) and not for production. + # -- The GCP Pricing API requires a key. This is supplied just for evaluation. + cloudProviderApiKey: "" + # -- Default cluster ID to use if cluster_id is not set in Prometheus metrics. + defaultClusterId: 'default-cluster' + image: + # -- Exporter container image registry + registry: ghcr.io + # -- Exporter container image name + repository: opencost/opencost + # -- Exporter container image tag + tag: "1.111.0@sha256:6aa68e52a24b14ba41f23db08d1b9db1429a1c0300f4c0381ecc2c61fc311a97" + # -- Exporter container image pull policy + pullPolicy: IfNotPresent + # -- Override the full image name for development purposes + fullImageName: null + # -- List of extra arguments for the command, e.g.: log-format=json + extraArgs: [] + # -- Number of OpenCost replicas to run + replicas: 1 + resources: + # -- CPU/Memory resource requests + requests: + cpu: '10m' + memory: '55Mi' + # -- CPU/Memory resource limits + limits: + cpu: '999m' + memory: '1Gi' + # Startup probe configuration + startupProbe: + # -- Whether probe is enabled + enabled: true + # -- Probe path + path: /healthz + # -- Number of seconds before probe is initiated + initialDelaySeconds: 10 + # -- Probe frequency in seconds + periodSeconds: 5 + # -- Number of failures for probe to be considered failed + failureThreshold: 30 + # Liveness probe configuration + livenessProbe: + # -- Whether probe is enabled + enabled: true + # -- Probe path + path: /healthz + # -- Number of seconds before probe is initiated + initialDelaySeconds: 10 + # -- Probe frequency in seconds + periodSeconds: 20 + # -- Number of failures for probe to be considered failed + failureThreshold: 3 + # Readiness probe configuration + readinessProbe: + # -- Whether probe is enabled + enabled: true + # -- Probe path + path: /healthz + # -- Number of seconds before probe is initiated + initialDelaySeconds: 10 + # -- Probe frequency in seconds + periodSeconds: 10 + # -- Number of failures for probe to be considered failed + failureThreshold: 3 + # -- The security options the container should be run with + securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + + # Path of CSV file + csv_path: "" + + # Persistent volume claim for storing the data. eg: csv file + persistence: + enabled: false + # -- Annotations for persistent volume + annotations: {} + # -- Access mode for persistent volume + accessMode: "" + # -- Storage class for persistent volume + storageClass: "" + # -- Size for persistent volume + size: "" + + aws: + # -- AWS secret access key + secret_access_key: "" + # -- AWS secret key id + access_key_id: "" + # -- A list of volume mounts to be added to the pod + extraVolumeMounts: [] + # -- List of additional environment variables to set in the container + env: [] + # -- Any extra environment variables you would like to pass on to the pod + extraEnv: {} + # FOO: BAR + # For example, if accessing mimir directly and getting 401 Unauthorized + # PROMETHEUS_HEADER_X_SCOPE_ORGID: anonymous + customPricing: + # -- Enables custom pricing configuration + enabled: false + # -- Customize the configmap name used for custom pricing + configmapName: custom-pricing-model + # -- Path for the pricing configuration. + configPath: /tmp/custom-config + # -- Configures the pricing model provided in the values file. + createConfigmap: true + # -- Sets the provider type for the custom pricing file. + provider: custom + # -- More information about these values here: https://www.opencost.io/docs/configuration/on-prem#custom-pricing-using-the-opencost-helm-chart + costModel: + description: Modified pricing configuration. + CPU: 1.25 + spotCPU: 0.006655 + RAM: 0.50 + spotRAM: 0.000892 + GPU: 0.95 + storage: 0.25 + zoneNetworkEgress: 0.01 + regionNetworkEgress: 0.01 + internetNetworkEgress: 0.12 + + dataRetention: + dailyResolutionDays: 15 + + carbonCost: + # -- Enable carbon cost exposed in the API + enabled: false + + cloudCost: + # -- Enable cloud cost ingestion and querying, dependant on valid integration credentials + enabled: false + # -- Number of hours between each run of the Cloud Cost pipeline + refreshRateHours: 6 + # -- Number of days into the past that a Cloud Cost standard run will query for + runWindowDays: 3 + # -- The number of standard runs before a Month-to-Date run occurs + monthToDateInterval: 6 + # -- The max number of days that any single query will be made to construct Cloud Costs + queryWindowDays: 7 + + + metrics: + kubeStateMetrics: + # -- (bool) Enable emission of pod annotations + emitPodAnnotations: ~ + # -- (bool) Enable emission of namespace annotations + emitNamespaceAnnotations: ~ + # -- (bool) Enable emission of KSM v1 metrics + emitKsmV1Metrics: ~ + # -- (bool) Enable only emission of KSM v1 metrics that do not exist in KSM 2 by default + emitKsmV1MetricsOnly: ~ + + serviceMonitor: + # -- Create ServiceMonitor resource for scraping metrics using PrometheusOperator + enabled: false + # -- Additional labels to add to the ServiceMonitor + additionalLabels: {} + # -- Specify if the ServiceMonitor will be deployed into a different namespace (blank deploys into same namespace as chart) + namespace: "" + # -- Interval at which metrics should be scraped + scrapeInterval: 30s + # -- Timeout after which the scrape is ended + scrapeTimeout: 10s + # -- HonorLabels chooses the metric's labels on collisions with target labels + honorLabels: true + # -- RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields + relabelings: [] + # -- MetricRelabelConfigs to apply to samples before ingestion + metricRelabelings: [] + # -- extra Endpoints to add to the ServiceMonitor. Useful for scraping sidecars + extraEndpoints: [] + # - port: oauth-metrics + # path: /metrics + # -- HTTP scheme used for scraping. Defaults to `http` + scheme: http + # -- TLS configuration for scraping metrics + tlsConfig: {} + # caFile: /etc/prom-certs/root-cert.pem + # certFile: /etc/prom-certs/cert-chain.pem + # insecureSkipVerify: true + # keyFile: /etc/prom-certs/key.pem + + config: + # -- Enables creating the metrics.json configuration as a ConfigMap + enabled: false + # -- Customize the configmap name used for metrics + configmapName: custom-metrics + # -- List of metrics to be disabled + disabledMetrics: [] + # - + # - + + prometheus: + # -- Secret name that contains credentials for Prometheus + secret_name: ~ + # -- Existing secret name that contains credentials for Prometheus + existingSecretName: ~ + # -- Prometheus Basic auth username + username: "" + # -- Key in the secret that references the username + username_key: DB_BASIC_AUTH_USERNAME + # -- Prometheus Basic auth password + password: "" + # -- Key in the secret that references the password + password_key: DB_BASIC_AUTH_PW + # -- Prometheus Bearer token + bearer_token: "" + bearer_token_key: DB_BEARER_TOKEN + external: + # -- Use external Prometheus (eg. Grafana Cloud) + enabled: false + # -- External Prometheus url + url: "https://prometheus.example.com/prometheus" + internal: + # -- Use in-cluster Prometheus + enabled: true + # -- Service name of in-cluster Prometheus + serviceName: prometheus-server + # -- Namespace of in-cluster Prometheus + namespaceName: prometheus-system + # -- Service port of in-cluster Prometheus + port: 80 + amp: + # -- Use Amazon Managed Service for Prometheus (AMP) + enabled: false # If true, opencost will be configured to remote_write and query from Amazon Managed Service for Prometheus. + # -- Workspace ID for AMP + workspaceId: "" + thanos: + enabled: false + queryOffset: '' + maxSourceResolution: '' + internal: + enabled: true + serviceName: my-thanos-query + namespaceName: opencost + port: 10901 + external: + enabled: false + url: 'https://thanos-query.example.com/thanos' + + ui: + # -- Enable OpenCost UI + enabled: true + image: + # -- UI container image registry + registry: ghcr.io + # -- UI container image name + repository: opencost/opencost-ui + # -- UI container image tag + # @default -- `""` (use appVersion in Chart.yaml) + tag: "1.111.0@sha256:f7221e7a708d71663f5eca6c238268757eb4352f3e9f46b1029d33ab4e53fd8a" + # -- UI container image pull policy + pullPolicy: IfNotPresent + # -- Override the full image name for development purposes + fullImageName: null + resources: + # -- CPU/Memory resource requests + requests: + cpu: '10m' + memory: '55Mi' + # -- CPU/Memory resource limits + limits: + cpu: '999m' + memory: '1Gi' + # used in the default.nginx.conf if you want to switch for using with Docker + # apiServer: 0.0.0.0 + uiPort: 9090 + # Liveness probe configuration + livenessProbe: + # -- Whether probe is enabled + enabled: true + # -- Probe path + path: /healthz + # -- Number of seconds before probe is initiated + initialDelaySeconds: 30 + # -- Probe frequency in seconds + periodSeconds: 10 + # -- Number of failures for probe to be considered failed + failureThreshold: 3 + # Readiness probe configuration + readinessProbe: + # -- Whether probe is enabled + enabled: true + # -- Probe path + path: /healthz + # -- Number of seconds before probe is initiated + initialDelaySeconds: 30 + # -- Probe frequency in seconds + periodSeconds: 10 + # -- Number of failures for probe to be considered failed + failureThreshold: 3 + # -- The security options the container should be run with + securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + + # -- A list of environment variables to be added to the pod + extraEnv: [] + + # -- A list of volume mounts to be added to the pod + extraVolumeMounts: [] + + ingress: + # -- Ingress for OpenCost UI + enabled: false + # -- Ingress controller which implements the resource + ingressClassName: "" + # -- Annotations for Ingress resource + annotations: {} + # kubernetes.io/tls-acme: "true" + # -- A list of host rules used to configure the Ingress + # @default -- See [values.yaml](values.yaml) + hosts: + - host: example.local + paths: + - / + # -- Redirect ingress to an extraPort defined on the service such as oauth-proxy + servicePort: http-ui + # servicePort: oauth-proxy + # -- Ingress TLS configuration + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + + sigV4Proxy: + image: public.ecr.aws/aws-observability/aws-sigv4-proxy:latest + imagePullPolicy: IfNotPresent + name: aps + port: 8005 + region: us-west-2 # The AWS region + host: aps-workspaces.us-west-2.amazonaws.com # The hostname for AMP service. + # role_arn: arn:aws:iam:::role/role-name # The AWS IAM role to assume. + extraEnv: # Pass extra env variables to sigV4Proxy + # - name: AWS_ACCESS_KEY_ID + # value: + # - name: AWS_SECRET_ACCESS_KEY + # value: + resources: {} + # limits: + # cpu: 200m + # memory: 500Mi + # requests: + # cpu: 20m + # memory: 32Mi + securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 65534 + # -- Toleration labels for pod assignment + tolerations: [] + # -- Node labels for pod assignment + nodeSelector: {} + # -- Affinity settings for pod assignment + affinity: {} + # -- Assign custom TopologySpreadConstraints rules + topologySpreadConstraints: [] + + # -- extra sidecars to add to the pod. Useful for things like oauth-proxy for the UI + extraContainers: [] + # - name: oauth-proxy + # image: quay.io/oauth2-proxy/oauth2-proxy:v7.5.1 + # args: + # - --upstream=http://127.0.0.1:9090 + # - --http-address=0.0.0.0:8081 + # - --metrics-address=0.0.0.0:8082 + # - ... + # ports: + # - name: oauth-proxy + # containerPort: 8081 + # protocol: TCP + # - name: oauth-metrics + # containerPort: 8082 + # protocol: TCP + # resources: {} + +# -- A list of volumes to be added to the pod +extraVolumes: [] diff --git a/packages/system/opencost/templates/vmservicescrape.yaml b/packages/system/opencost/templates/vmservicescrape.yaml new file mode 100644 index 00000000..fca9deef --- /dev/null +++ b/packages/system/opencost/templates/vmservicescrape.yaml @@ -0,0 +1,11 @@ +apiVersion: operator.victoriametrics.com/v1beta1 +kind: VMServiceScrape +metadata: + name: opencost +spec: + endpoints: + - port: http + path: /metrics + selector: + matchLabels: + app.kubernetes.io/instance: opencost diff --git a/packages/system/opencost/values.yaml b/packages/system/opencost/values.yaml new file mode 100644 index 00000000..c1d02a5d --- /dev/null +++ b/packages/system/opencost/values.yaml @@ -0,0 +1,12 @@ +opencost: + opencost: + prometheus: + external: + enabled: true + url: "http://vmselect-shortterm.tenant-root.svc:8481/select/0/prometheus" + internal: + enabled: false + + customPricing: + enabled: true + createConfigmap: true