From f28f437d39cac3062c2681961c544de8bc5b282c Mon Sep 17 00:00:00 2001 From: Adam Pickering Date: Tue, 11 Jun 2024 11:17:00 -0600 Subject: [PATCH] Remove MetalLB (#1029) --- assets/icons/metallb.png | Bin 19036 -> 0 bytes assets/metallb/metallb-0.13.11.tgz | Bin 24505 -> 0 bytes assets/metallb/metallb-0.13.12.tgz | Bin 24502 -> 0 bytes assets/metallb/metallb-0.14.3.tgz | Bin 38876 -> 0 bytes assets/metallb/metallb-0.14.4.tgz | Bin 39906 -> 0 bytes assets/metallb/metallb-0.14.5.tgz | Bin 39978 -> 0 bytes charts/metallb/metallb/.helmignore | 23 - charts/metallb/metallb/Chart.lock | 9 - charts/metallb/metallb/Chart.yaml | 27 - charts/metallb/metallb/README.md | 167 --- .../metallb/metallb/charts/crds/.helmignore | 23 - charts/metallb/metallb/charts/crds/Chart.yaml | 10 - charts/metallb/metallb/charts/crds/README.md | 14 - .../metallb/charts/crds/templates/crds.yaml | 1160 ----------------- .../metallb/charts/frr-k8s/.helmignore | 23 - .../metallb/metallb/charts/frr-k8s/Chart.lock | 6 - .../metallb/metallb/charts/frr-k8s/Chart.yaml | 16 - .../metallb/metallb/charts/frr-k8s/README.md | 96 -- .../charts/frr-k8s/charts/crds/.helmignore | 23 - .../charts/frr-k8s/charts/crds/Chart.yaml | 10 - .../charts/frr-k8s/charts/crds/README.md | 14 - .../frrk8s.metallb.io_frrconfigurations.yaml | 424 ------ .../frrk8s.metallb.io_frrnodestates.yaml | 61 - .../charts/frr-k8s/templates/NOTES.txt | 4 - .../charts/frr-k8s/templates/_helpers.tpl | 63 - .../charts/frr-k8s/templates/controller.yaml | 431 ------ .../charts/frr-k8s/templates/rbac.yaml | 73 -- .../frr-k8s/templates/service-accounts.yaml | 16 - .../frr-k8s/templates/service-monitor.yaml | 128 -- .../charts/frr-k8s/templates/webhooks.yaml | 159 --- .../metallb/charts/frr-k8s/values.schema.json | 387 ------ .../metallb/charts/frr-k8s/values.yaml | 173 --- charts/metallb/metallb/policy/controller.rego | 16 - charts/metallb/metallb/policy/rbac.rego | 27 - charts/metallb/metallb/policy/speaker.rego | 30 - charts/metallb/metallb/templates/NOTES.txt | 4 - charts/metallb/metallb/templates/_helpers.tpl | 113 -- .../metallb/metallb/templates/controller.yaml | 194 --- .../templates/deprecated_configInline.yaml | 3 - .../metallb/templates/exclude-l2-config.yaml | 25 - .../metallb/metallb/templates/podmonitor.yaml | 106 -- .../metallb/templates/prometheusrules.yaml | 84 -- charts/metallb/metallb/templates/rbac.yaml | 212 --- .../metallb/templates/service-accounts.yaml | 30 - .../metallb/templates/servicemonitor.yaml | 193 --- charts/metallb/metallb/templates/speaker.yaml | 553 -------- .../metallb/metallb/templates/webhooks.yaml | 150 --- charts/metallb/metallb/values.schema.json | 448 ------- charts/metallb/metallb/values.yaml | 363 ------ index.yaml | 148 --- packages/metallb/metallb/upstream.yaml | 7 - 51 files changed, 6246 deletions(-) delete mode 100644 assets/icons/metallb.png delete mode 100644 assets/metallb/metallb-0.13.11.tgz delete mode 100644 assets/metallb/metallb-0.13.12.tgz delete mode 100644 assets/metallb/metallb-0.14.3.tgz delete mode 100644 assets/metallb/metallb-0.14.4.tgz delete mode 100644 assets/metallb/metallb-0.14.5.tgz delete mode 100644 charts/metallb/metallb/.helmignore delete mode 100644 charts/metallb/metallb/Chart.lock delete mode 100644 charts/metallb/metallb/Chart.yaml delete mode 100644 charts/metallb/metallb/README.md delete mode 100644 charts/metallb/metallb/charts/crds/.helmignore delete mode 100644 charts/metallb/metallb/charts/crds/Chart.yaml delete mode 100644 charts/metallb/metallb/charts/crds/README.md delete mode 100644 charts/metallb/metallb/charts/crds/templates/crds.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/.helmignore delete mode 100644 charts/metallb/metallb/charts/frr-k8s/Chart.lock delete mode 100644 charts/metallb/metallb/charts/frr-k8s/Chart.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/README.md delete mode 100644 charts/metallb/metallb/charts/frr-k8s/charts/crds/.helmignore delete mode 100644 charts/metallb/metallb/charts/frr-k8s/charts/crds/Chart.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/charts/crds/README.md delete mode 100644 charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrconfigurations.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrnodestates.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/templates/NOTES.txt delete mode 100644 charts/metallb/metallb/charts/frr-k8s/templates/_helpers.tpl delete mode 100644 charts/metallb/metallb/charts/frr-k8s/templates/controller.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/templates/rbac.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/templates/service-accounts.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/templates/service-monitor.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/templates/webhooks.yaml delete mode 100644 charts/metallb/metallb/charts/frr-k8s/values.schema.json delete mode 100644 charts/metallb/metallb/charts/frr-k8s/values.yaml delete mode 100644 charts/metallb/metallb/policy/controller.rego delete mode 100644 charts/metallb/metallb/policy/rbac.rego delete mode 100644 charts/metallb/metallb/policy/speaker.rego delete mode 100644 charts/metallb/metallb/templates/NOTES.txt delete mode 100644 charts/metallb/metallb/templates/_helpers.tpl delete mode 100644 charts/metallb/metallb/templates/controller.yaml delete mode 100644 charts/metallb/metallb/templates/deprecated_configInline.yaml delete mode 100644 charts/metallb/metallb/templates/exclude-l2-config.yaml delete mode 100644 charts/metallb/metallb/templates/podmonitor.yaml delete mode 100644 charts/metallb/metallb/templates/prometheusrules.yaml delete mode 100644 charts/metallb/metallb/templates/rbac.yaml delete mode 100644 charts/metallb/metallb/templates/service-accounts.yaml delete mode 100644 charts/metallb/metallb/templates/servicemonitor.yaml delete mode 100644 charts/metallb/metallb/templates/speaker.yaml delete mode 100644 charts/metallb/metallb/templates/webhooks.yaml delete mode 100644 charts/metallb/metallb/values.schema.json delete mode 100644 charts/metallb/metallb/values.yaml delete mode 100644 packages/metallb/metallb/upstream.yaml diff --git a/assets/icons/metallb.png b/assets/icons/metallb.png deleted file mode 100644 index 8a19cd00bb3aa60a9b3a0a2f9d5c9bf20ab49a2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19036 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 cQ`qTTam5u^T+z$_0RRC1|EOC}B>Dc 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 diff --git a/assets/metallb/metallb-0.14.3.tgz b/assets/metallb/metallb-0.14.3.tgz deleted file mode 100644 index 372f502a6510c2359764eecc8a0f15ae4a3187c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38876 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 AUH||9 diff --git a/assets/metallb/metallb-0.14.4.tgz b/assets/metallb/metallb-0.14.4.tgz deleted file mode 100644 index 7fc25ea143330df39aae7dfb664a2723c479eaa2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39906 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 JNKdFp{|o-%jG6!d diff --git a/assets/metallb/metallb-0.14.5.tgz b/assets/metallb/metallb-0.14.5.tgz deleted file mode 100644 index 3675351e7c564fb30fc3bb6aeea937a1f3dd17c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39978 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

JY4o-aTD^wd>NZA~ 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%0D_D)srogvSi8SOQo12`s1Q{xs;ZcOQt11 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 uvY0eAa!8qa*6{Un7a(Q%w*KeB= 1.19.0-0' - catalog.cattle.io/namespace: metallb-system - catalog.cattle.io/release-name: metallb -apiVersion: v2 -appVersion: v0.14.5 -dependencies: -- condition: crds.enabled - name: crds - repository: file://./charts/crds - version: 0.14.5 -- condition: frrk8s.enabled - name: frr-k8s - repository: file://./charts/frr-k8s - version: 0.0.11 -description: A network load-balancer implementation for Kubernetes using standard - routing protocols -home: https://metallb.universe.tf -icon: https://metallb.universe.tf/images/logo/metallb-blue.png -kubeVersion: '>= 1.19.0-0' -name: metallb -sources: -- https://github.com/metallb/metallb -type: application -version: 0.14.5 diff --git a/charts/metallb/metallb/README.md b/charts/metallb/metallb/README.md deleted file mode 100644 index 66f3a6171..000000000 --- a/charts/metallb/metallb/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# metallb - -![Version: 0.0.0](https://img.shields.io/badge/Version-0.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.0.0](https://img.shields.io/badge/AppVersion-v0.0.0-informational?style=flat-square) - -A network load-balancer implementation for Kubernetes using standard routing protocols - -**Homepage:** - -## Source Code - -* - -## Requirements - -Kubernetes: `>= 1.19.0-0` - -| Repository | Name | Version | -|------------|------|---------| -| | crds | 0.0.0 | -| https://metallb.github.io/frr-k8s | frr-k8s | 0.0.11 | - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| controller.affinity | object | `{}` | | -| controller.enabled | bool | `true` | | -| controller.extraContainers | list | `[]` | | -| controller.image.pullPolicy | string | `nil` | | -| controller.image.repository | string | `"quay.io/metallb/controller"` | | -| controller.image.tag | string | `nil` | | -| controller.labels | object | `{}` | | -| controller.livenessProbe.enabled | bool | `true` | | -| controller.livenessProbe.failureThreshold | int | `3` | | -| controller.livenessProbe.initialDelaySeconds | int | `10` | | -| controller.livenessProbe.periodSeconds | int | `10` | | -| controller.livenessProbe.successThreshold | int | `1` | | -| controller.livenessProbe.timeoutSeconds | int | `1` | | -| controller.logLevel | string | `"info"` | Controller log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none` | -| controller.nodeSelector | object | `{}` | | -| controller.podAnnotations | object | `{}` | | -| controller.priorityClassName | string | `""` | | -| controller.readinessProbe.enabled | bool | `true` | | -| controller.readinessProbe.failureThreshold | int | `3` | | -| controller.readinessProbe.initialDelaySeconds | int | `10` | | -| controller.readinessProbe.periodSeconds | int | `10` | | -| controller.readinessProbe.successThreshold | int | `1` | | -| controller.readinessProbe.timeoutSeconds | int | `1` | | -| controller.resources | object | `{}` | | -| controller.runtimeClassName | string | `""` | | -| controller.securityContext.fsGroup | int | `65534` | | -| controller.securityContext.runAsNonRoot | bool | `true` | | -| controller.securityContext.runAsUser | int | `65534` | | -| controller.serviceAccount.annotations | object | `{}` | | -| controller.serviceAccount.create | bool | `true` | | -| controller.serviceAccount.name | string | `""` | | -| controller.strategy.type | string | `"RollingUpdate"` | | -| controller.tlsCipherSuites | string | `""` | | -| controller.tlsMinVersion | string | `"VersionTLS12"` | | -| controller.tolerations | list | `[]` | | -| crds.enabled | bool | `true` | | -| crds.validationFailurePolicy | string | `"Fail"` | | -| frrk8s.enabled | bool | `false` | | -| fullnameOverride | string | `""` | | -| imagePullSecrets | list | `[]` | | -| loadBalancerClass | string | `""` | | -| nameOverride | string | `""` | | -| prometheus.controllerMetricsTLSSecret | string | `""` | | -| prometheus.metricsPort | int | `7472` | | -| prometheus.namespace | string | `""` | | -| prometheus.podMonitor.additionalLabels | object | `{}` | | -| prometheus.podMonitor.annotations | object | `{}` | | -| prometheus.podMonitor.enabled | bool | `false` | | -| prometheus.podMonitor.interval | string | `nil` | | -| prometheus.podMonitor.jobLabel | string | `"app.kubernetes.io/name"` | | -| prometheus.podMonitor.metricRelabelings | list | `[]` | | -| prometheus.podMonitor.relabelings | list | `[]` | | -| prometheus.prometheusRule.additionalLabels | object | `{}` | | -| prometheus.prometheusRule.addressPoolExhausted.enabled | bool | `true` | | -| prometheus.prometheusRule.addressPoolExhausted.labels.severity | string | `"alert"` | | -| prometheus.prometheusRule.addressPoolUsage.enabled | bool | `true` | | -| prometheus.prometheusRule.addressPoolUsage.thresholds[0].labels.severity | string | `"warning"` | | -| prometheus.prometheusRule.addressPoolUsage.thresholds[0].percent | int | `75` | | -| prometheus.prometheusRule.addressPoolUsage.thresholds[1].labels.severity | string | `"warning"` | | -| prometheus.prometheusRule.addressPoolUsage.thresholds[1].percent | int | `85` | | -| prometheus.prometheusRule.addressPoolUsage.thresholds[2].labels.severity | string | `"alert"` | | -| prometheus.prometheusRule.addressPoolUsage.thresholds[2].percent | int | `95` | | -| prometheus.prometheusRule.annotations | object | `{}` | | -| prometheus.prometheusRule.bgpSessionDown.enabled | bool | `true` | | -| prometheus.prometheusRule.bgpSessionDown.labels.severity | string | `"alert"` | | -| prometheus.prometheusRule.configNotLoaded.enabled | bool | `true` | | -| prometheus.prometheusRule.configNotLoaded.labels.severity | string | `"warning"` | | -| prometheus.prometheusRule.enabled | bool | `false` | | -| prometheus.prometheusRule.extraAlerts | list | `[]` | | -| prometheus.prometheusRule.staleConfig.enabled | bool | `true` | | -| prometheus.prometheusRule.staleConfig.labels.severity | string | `"warning"` | | -| prometheus.rbacPrometheus | bool | `true` | | -| prometheus.rbacProxy.pullPolicy | string | `nil` | | -| prometheus.rbacProxy.repository | string | `"gcr.io/kubebuilder/kube-rbac-proxy"` | | -| prometheus.rbacProxy.tag | string | `"v0.12.0"` | | -| prometheus.scrapeAnnotations | bool | `false` | | -| prometheus.serviceAccount | string | `""` | | -| prometheus.serviceMonitor.controller.additionalLabels | object | `{}` | | -| prometheus.serviceMonitor.controller.annotations | object | `{}` | | -| prometheus.serviceMonitor.controller.tlsConfig.insecureSkipVerify | bool | `true` | | -| prometheus.serviceMonitor.enabled | bool | `false` | | -| prometheus.serviceMonitor.interval | string | `nil` | | -| prometheus.serviceMonitor.jobLabel | string | `"app.kubernetes.io/name"` | | -| prometheus.serviceMonitor.metricRelabelings | list | `[]` | | -| prometheus.serviceMonitor.relabelings | list | `[]` | | -| prometheus.serviceMonitor.speaker.additionalLabels | object | `{}` | | -| prometheus.serviceMonitor.speaker.annotations | object | `{}` | | -| prometheus.serviceMonitor.speaker.tlsConfig.insecureSkipVerify | bool | `true` | | -| prometheus.speakerMetricsTLSSecret | string | `""` | | -| rbac.create | bool | `true` | | -| speaker.affinity | object | `{}` | | -| speaker.enabled | bool | `true` | | -| speaker.excludeInterfaces.enabled | bool | `true` | | -| speaker.extraContainers | list | `[]` | | -| speaker.frr.enabled | bool | `true` | | -| speaker.frr.image.pullPolicy | string | `nil` | | -| speaker.frr.image.repository | string | `"quay.io/frrouting/frr"` | | -| speaker.frr.image.tag | string | `"9.0.2"` | | -| speaker.frr.metricsPort | int | `7473` | | -| speaker.frr.resources | object | `{}` | | -| speaker.frrMetrics.resources | object | `{}` | | -| speaker.ignoreExcludeLB | bool | `false` | | -| speaker.image.pullPolicy | string | `nil` | | -| speaker.image.repository | string | `"quay.io/metallb/speaker"` | | -| speaker.image.tag | string | `nil` | | -| speaker.labels | object | `{}` | | -| speaker.livenessProbe.enabled | bool | `true` | | -| speaker.livenessProbe.failureThreshold | int | `3` | | -| speaker.livenessProbe.initialDelaySeconds | int | `10` | | -| speaker.livenessProbe.periodSeconds | int | `10` | | -| speaker.livenessProbe.successThreshold | int | `1` | | -| speaker.livenessProbe.timeoutSeconds | int | `1` | | -| speaker.logLevel | string | `"info"` | Speaker log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none` | -| speaker.memberlist.enabled | bool | `true` | | -| speaker.memberlist.mlBindAddrOverride | string | `""` | | -| speaker.memberlist.mlBindPort | int | `7946` | | -| speaker.memberlist.mlSecretKeyPath | string | `"/etc/ml_secret_key"` | | -| speaker.nodeSelector | object | `{}` | | -| speaker.podAnnotations | object | `{}` | | -| speaker.priorityClassName | string | `""` | | -| speaker.readinessProbe.enabled | bool | `true` | | -| speaker.readinessProbe.failureThreshold | int | `3` | | -| speaker.readinessProbe.initialDelaySeconds | int | `10` | | -| speaker.readinessProbe.periodSeconds | int | `10` | | -| speaker.readinessProbe.successThreshold | int | `1` | | -| speaker.readinessProbe.timeoutSeconds | int | `1` | | -| speaker.reloader.resources | object | `{}` | | -| speaker.resources | object | `{}` | | -| speaker.runtimeClassName | string | `""` | | -| speaker.securityContext | object | `{}` | | -| speaker.serviceAccount.annotations | object | `{}` | | -| speaker.serviceAccount.create | bool | `true` | | -| speaker.serviceAccount.name | string | `""` | | -| speaker.startupProbe.enabled | bool | `true` | | -| speaker.startupProbe.failureThreshold | int | `30` | | -| speaker.startupProbe.periodSeconds | int | `5` | | -| speaker.tolerateMaster | bool | `true` | | -| speaker.tolerations | list | `[]` | | -| speaker.updateStrategy.type | string | `"RollingUpdate"` | | - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0) diff --git a/charts/metallb/metallb/charts/crds/.helmignore b/charts/metallb/metallb/charts/crds/.helmignore deleted file mode 100644 index 0e8a0eb36..000000000 --- a/charts/metallb/metallb/charts/crds/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/charts/metallb/metallb/charts/crds/Chart.yaml b/charts/metallb/metallb/charts/crds/Chart.yaml deleted file mode 100644 index 1cd137c77..000000000 --- a/charts/metallb/metallb/charts/crds/Chart.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v2 -appVersion: v0.14.5 -description: MetalLB CRDs -home: https://metallb.universe.tf -icon: https://metallb.universe.tf/images/logo/metallb-white.png -name: crds -sources: -- https://github.com/metallb/metallb -type: application -version: 0.14.5 diff --git a/charts/metallb/metallb/charts/crds/README.md b/charts/metallb/metallb/charts/crds/README.md deleted file mode 100644 index 15bf8a7b7..000000000 --- a/charts/metallb/metallb/charts/crds/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# crds - -![Version: 0.0.0](https://img.shields.io/badge/Version-0.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.0.0](https://img.shields.io/badge/AppVersion-v0.0.0-informational?style=flat-square) - -MetalLB CRDs - -**Homepage:** - -## Source Code - -* - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0) diff --git a/charts/metallb/metallb/charts/crds/templates/crds.yaml b/charts/metallb/metallb/charts/crds/templates/crds.yaml deleted file mode 100644 index 79497f125..000000000 --- a/charts/metallb/metallb/charts/crds/templates/crds.yaml +++ /dev/null @@ -1,1160 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: bfdprofiles.metallb.io -spec: - group: metallb.io - names: - kind: BFDProfile - listKind: BFDProfileList - plural: bfdprofiles - singular: bfdprofile - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.passiveMode - name: Passive Mode - type: boolean - - jsonPath: .spec.transmitInterval - name: Transmit Interval - type: integer - - jsonPath: .spec.receiveInterval - name: Receive Interval - type: integer - - jsonPath: .spec.detectMultiplier - name: Multiplier - type: integer - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - BFDProfile represents the settings of the bfd session that can be - optionally associated with a BGP session. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: BFDProfileSpec defines the desired state of BFDProfile. - properties: - detectMultiplier: - description: |- - Configures the detection multiplier to determine - packet loss. The remote transmission interval will be multiplied - by this value to determine the connection loss detection timer. - format: int32 - maximum: 255 - minimum: 2 - type: integer - echoInterval: - description: |- - Configures the minimal echo receive transmission - interval that this system is capable of handling in milliseconds. - Defaults to 50ms - format: int32 - maximum: 60000 - minimum: 10 - type: integer - echoMode: - description: |- - Enables or disables the echo transmission mode. - This mode is disabled by default, and not supported on multi - hops setups. - type: boolean - minimumTtl: - description: |- - For multi hop sessions only: configure the minimum - expected TTL for an incoming BFD control packet. - format: int32 - maximum: 254 - minimum: 1 - type: integer - passiveMode: - description: |- - Mark session as passive: a passive session will not - attempt to start the connection and will wait for control packets - from peer before it begins replying. - type: boolean - receiveInterval: - description: |- - The minimum interval that this system is capable of - receiving control packets in milliseconds. - Defaults to 300ms. - format: int32 - maximum: 60000 - minimum: 10 - type: integer - transmitInterval: - description: |- - The minimum transmission interval (less jitter) - that this system wants to use to send BFD control packets in - milliseconds. Defaults to 300ms - format: int32 - maximum: 60000 - minimum: 10 - type: integer - type: object - status: - description: BFDProfileStatus defines the observed state of BFDProfile. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: bgpadvertisements.metallb.io -spec: - group: metallb.io - names: - kind: BGPAdvertisement - listKind: BGPAdvertisementList - plural: bgpadvertisements - singular: bgpadvertisement - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.ipAddressPools - name: IPAddressPools - type: string - - jsonPath: .spec.ipAddressPoolSelectors - name: IPAddressPool Selectors - type: string - - jsonPath: .spec.peers - name: Peers - type: string - - jsonPath: .spec.nodeSelectors - name: Node Selectors - priority: 10 - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - BGPAdvertisement allows to advertise the IPs coming - from the selected IPAddressPools via BGP, setting the parameters of the - BGP Advertisement. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: BGPAdvertisementSpec defines the desired state of BGPAdvertisement. - properties: - aggregationLength: - default: 32 - description: The aggregation-length advertisement option lets you “roll up” the /32s into a larger prefix. Defaults to 32. Works for IPv4 addresses. - format: int32 - minimum: 1 - type: integer - aggregationLengthV6: - default: 128 - description: The aggregation-length advertisement option lets you “roll up” the /128s into a larger prefix. Defaults to 128. Works for IPv6 addresses. - format: int32 - type: integer - communities: - description: |- - The BGP communities to be associated with the announcement. Each item can be a standard community of the - form 1234:1234, a large community of the form large:1234:1234:1234 or the name of an alias defined in the - Community CRD. - items: - type: string - type: array - ipAddressPoolSelectors: - description: |- - A selector for the IPAddressPools which would get advertised via this advertisement. - If no IPAddressPool is selected by this or by the list, the advertisement is applied to all the IPAddressPools. - items: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: array - ipAddressPools: - description: The list of IPAddressPools to advertise via this advertisement, selected by name. - items: - type: string - type: array - localPref: - description: |- - The BGP LOCAL_PREF attribute which is used by BGP best path algorithm, - Path with higher localpref is preferred over one with lower localpref. - format: int32 - type: integer - nodeSelectors: - description: NodeSelectors allows to limit the nodes to announce as next hops for the LoadBalancer IP. When empty, all the nodes having are announced as next hops. - items: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: array - peers: - description: |- - Peers limits the bgppeer to advertise the ips of the selected pools to. - When empty, the loadbalancer IP is announced to all the BGPPeers configured. - items: - type: string - type: array - type: object - status: - description: BGPAdvertisementStatus defines the observed state of BGPAdvertisement. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: bgppeers.metallb.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlGWlRDQ0EwMmdBd0lCQWdJVU5GRW1XcTM3MVpKdGkrMmlSQzk1WmpBV1MxZ3dEUVlKS29aSWh2Y05BUUVMDQpCUUF3UWpFTE1Ba0dBMVVFQmhNQ1dGZ3hGVEFUQmdOVkJBY01ERVJsWm1GMWJIUWdRMmwwZVRFY01Cb0dBMVVFDQpDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRBZUZ3MHlNakEzTVRrd09UTXlNek5hRncweU1qQTRNVGd3DQpPVE15TXpOYU1FSXhDekFKQmdOVkJBWVRBbGhZTVJVd0V3WURWUVFIREF4RVpXWmhkV3gwSUVOcGRIa3hIREFhDQpCZ05WQkFvTUUwUmxabUYxYkhRZ1EyOXRjR0Z1ZVNCTWRHUXdnZ0lpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElDDQpEd0F3Z2dJS0FvSUNBUUNxVFpxMWZRcC9vYkdlenhES0o3OVB3Ny94azJwellualNzMlkzb1ZYSm5sRmM4YjVlDQpma2ZZQnY2bndscW1keW5PL2phWFBaQmRQSS82aFdOUDBkdVhadEtWU0NCUUpyZzEyOGNXb3F0MGNTN3pLb1VpDQpvcU1tQ0QvRXVBeFFNZjhRZDF2c1gvVllkZ0poVTZBRXJLZEpIaXpFOUJtUkNkTDBGMW1OVW55Rk82UnRtWFZUDQpidkxsTDVYeTc2R0FaQVBLOFB4aVlDa0NtbDdxN0VnTWNiOXlLWldCYmlxQ3VkTXE5TGJLNmdKNzF6YkZnSXV4DQo1L1pXK2JraTB2RlplWk9ZODUxb1psckFUNzJvMDI4NHNTWW9uN0pHZVZkY3NoUnh5R1VpSFpSTzdkaXZVTDVTDQpmM2JmSDFYbWY1ZDQzT0NWTWRuUUV2NWVaOG8zeWVLa3ZrbkZQUGVJMU9BbjdGbDlFRVNNR2dhOGFaSG1URSttDQpsLzlMSmdDYjBnQmtPT0M0WnV4bWh2aERKV1EzWnJCS3pMQlNUZXN0NWlLNVlwcXRWVVk2THRyRW9FelVTK1lsDQpwWndXY2VQWHlHeHM5ZURsR3lNVmQraW15Y3NTU1UvVno2Mmx6MnZCS21NTXBkYldDQWhud0RsRTVqU2dyMjRRDQp0eGNXLys2N3d5KzhuQlI3UXdqVTFITndVRjBzeERWdEwrZ1NHVERnSEVZSlhZelYvT05zMy94TkpoVFNPSkxNDQpoeXNVdyttaGdackdhbUdXcHVIVU1DUitvTWJzMTc1UkcrQjJnUFFHVytPTjJnUTRyOXN2b0ZBNHBBQm8xd1dLDQpRYjRhY3pmeVVscElBOVFoSmFsZEY3S3dPSHVlV3gwRUNrNXg0T2tvVDBvWVp0dzFiR0JjRGtaSmF3SURBUUFCDQpvMU13VVRBZEJnTlZIUTRFRmdRVW90UlNIUm9IWTEyRFZ4R0NCdEhpb1g2ZmVFQXdId1lEVlIwakJCZ3dGb0FVDQpvdFJTSFJvSFkxMkRWeEdDQnRIaW9YNmZlRUF3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCDQpBUXNGQUFPQ0FnRUFSbkpsWWRjMTFHd0VxWnh6RDF2R3BDR2pDN2VWTlQ3aVY1d3IybXlybHdPYi9aUWFEa0xYDQpvVStaOVVXT1VlSXJTdzUydDdmQUpvVVAwSm5iYkMveVIrU1lqUGhvUXNiVHduOTc2ZldBWTduM3FMOXhCd1Y0DQphek41OXNjeUp0dlhMeUtOL2N5ak1ReDRLajBIMFg0bWJ6bzVZNUtzWWtYVU0vOEFPdWZMcEd0S1NGVGgrSEFDDQpab1Q5YnZHS25adnNHd0tYZFF0Wnh0akhaUjVqK3U3ZGtQOTJBT051RFNabS8rWVV4b2tBK09JbzdSR3BwSHNXDQo1ZTdNY0FTVXRtb1FORXd6dVFoVkJaRWQ1OGtKYjUrV0VWbGNzanlXNnRTbzErZ25tTWNqR1BsMWgxR2hVbjV4DQpFY0lWRnBIWXM5YWo1NmpBSjk1MVQvZjhMaWxmTlVnanBLQ0c1bnl0SUt3emxhOHNtdGlPdm1UNEpYbXBwSkI2DQo4bmdHRVluVjUrUTYwWFJ2OEhSSGp1VG9CRHVhaERrVDA2R1JGODU1d09FR2V4bkZpMXZYWUxLVllWb1V2MXRKDQo4dVdUR1pwNllDSVJldlBqbzg5ZytWTlJSaVFYUThJd0dybXE5c0RoVTlqTjA0SjdVL1RvRDFpNHE3VnlsRUc5DQorV1VGNkNLaEdBeTJIaEhwVncyTGFoOS9lUzdZMUZ1YURrWmhPZG1laG1BOCtqdHNZamJadnR5Mm1SWlF0UUZzDQpUU1VUUjREbUR2bVVPRVRmeStpRHdzK2RkWXVNTnJGeVVYV2dkMnpBQU4ydVl1UHFGY2pRcFNPODFzVTJTU3R3DQoxVzAyeUtYOGJEYmZFdjBzbUh3UzliQnFlSGo5NEM1Mjg0YXpsdTBmaUdpTm1OUEM4ckJLRmhBPQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ== - service: - name: metallb-webhook-service - namespace: {{ .Release.Namespace }} - path: /convert - conversionReviewVersions: - - v1beta1 - - v1beta2 - group: metallb.io - names: - kind: BGPPeer - listKind: BGPPeerList - plural: bgppeers - singular: bgppeer - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.peerAddress - name: Address - type: string - - jsonPath: .spec.peerASN - name: ASN - type: string - - jsonPath: .spec.bfdProfile - name: BFD Profile - type: string - - jsonPath: .spec.ebgpMultiHop - name: Multi Hops - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: BGPPeer is the Schema for the peers API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: BGPPeerSpec defines the desired state of Peer. - properties: - bfdProfile: - type: string - ebgpMultiHop: - description: EBGP peer is multi-hops away - type: boolean - holdTime: - description: Requested BGP hold time, per RFC4271. - type: string - keepaliveTime: - description: Requested BGP keepalive time, per RFC4271. - type: string - myASN: - description: AS number to use for the local end of the session. - format: int32 - maximum: 4294967295 - minimum: 0 - type: integer - nodeSelectors: - description: |- - Only connect to this peer on nodes that match one of these - selectors. - items: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - minItems: 1 - type: array - required: - - key - - operator - - values - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - type: array - password: - description: Authentication password for routers enforcing TCP MD5 authenticated sessions - type: string - peerASN: - description: AS number to expect from the remote end of the session. - format: int32 - maximum: 4294967295 - minimum: 0 - type: integer - peerAddress: - description: Address to dial when establishing the session. - type: string - peerPort: - description: Port to dial when establishing the session. - maximum: 16384 - minimum: 0 - type: integer - routerID: - description: BGP router ID to advertise to the peer - type: string - sourceAddress: - description: Source address to use when establishing the session. - type: string - required: - - myASN - - peerASN - - peerAddress - type: object - status: - description: BGPPeerStatus defines the observed state of Peer. - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.peerAddress - name: Address - type: string - - jsonPath: .spec.peerASN - name: ASN - type: string - - jsonPath: .spec.bfdProfile - name: BFD Profile - type: string - - jsonPath: .spec.ebgpMultiHop - name: Multi Hops - type: string - name: v1beta2 - schema: - openAPIV3Schema: - description: BGPPeer is the Schema for the peers API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: BGPPeerSpec defines the desired state of Peer. - properties: - bfdProfile: - description: The name of the BFD Profile to be used for the BFD session associated to the BGP session. If not set, the BFD session won't be set up. - type: string - connectTime: - description: Requested BGP connect time, controls how long BGP waits between connection attempts to a neighbor. - type: string - x-kubernetes-validations: - - message: connect time should be between 1 seconds to 65535 - rule: duration(self).getSeconds() >= 1 && duration(self).getSeconds() <= 65535 - - message: connect time should contain a whole number of seconds - rule: duration(self).getMilliseconds() % 1000 == 0 - disableMP: - default: false - description: To set if we want to disable MP BGP that will separate IPv4 and IPv6 route exchanges into distinct BGP sessions. - type: boolean - ebgpMultiHop: - description: To set if the BGPPeer is multi-hops away. Needed for FRR mode only. - type: boolean - holdTime: - description: Requested BGP hold time, per RFC4271. - type: string - keepaliveTime: - description: Requested BGP keepalive time, per RFC4271. - type: string - myASN: - description: AS number to use for the local end of the session. - format: int32 - maximum: 4294967295 - minimum: 0 - type: integer - nodeSelectors: - description: |- - Only connect to this peer on nodes that match one of these - selectors. - items: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: array - password: - description: Authentication password for routers enforcing TCP MD5 authenticated sessions - type: string - passwordSecret: - description: |- - passwordSecret is name of the authentication secret for BGP Peer. - the secret must be of type "kubernetes.io/basic-auth", and created in the - same namespace as the MetalLB deployment. The password is stored in the - secret as the key "password". - properties: - name: - description: name is unique within a namespace to reference a secret resource. - type: string - namespace: - description: namespace defines the space within which the secret name must be unique. - type: string - type: object - x-kubernetes-map-type: atomic - peerASN: - description: AS number to expect from the remote end of the session. - format: int32 - maximum: 4294967295 - minimum: 0 - type: integer - peerAddress: - description: Address to dial when establishing the session. - type: string - peerPort: - default: 179 - description: Port to dial when establishing the session. - maximum: 16384 - minimum: 0 - type: integer - routerID: - description: BGP router ID to advertise to the peer - type: string - sourceAddress: - description: Source address to use when establishing the session. - type: string - vrf: - description: |- - To set if we want to peer with the BGPPeer using an interface belonging to - a host vrf - type: string - required: - - myASN - - peerASN - - peerAddress - type: object - status: - description: BGPPeerStatus defines the observed state of Peer. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: communities.metallb.io -spec: - group: metallb.io - names: - kind: Community - listKind: CommunityList - plural: communities - singular: community - scope: Namespaced - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - Community is a collection of aliases for communities. - Users can define named aliases to be used in the BGPPeer CRD. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: CommunitySpec defines the desired state of Community. - properties: - communities: - items: - properties: - name: - description: The name of the alias for the community. - type: string - value: - description: |- - The BGP community value corresponding to the given name. Can be a standard community of the form 1234:1234 - or a large community of the form large:1234:1234:1234. - type: string - type: object - type: array - type: object - status: - description: CommunityStatus defines the observed state of Community. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: ipaddresspools.metallb.io -spec: - group: metallb.io - names: - kind: IPAddressPool - listKind: IPAddressPoolList - plural: ipaddresspools - singular: ipaddresspool - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.autoAssign - name: Auto Assign - type: boolean - - jsonPath: .spec.avoidBuggyIPs - name: Avoid Buggy IPs - type: boolean - - jsonPath: .spec.addresses - name: Addresses - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - IPAddressPool represents a pool of IP addresses that can be allocated - to LoadBalancer services. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: IPAddressPoolSpec defines the desired state of IPAddressPool. - properties: - addresses: - description: |- - A list of IP address ranges over which MetalLB has authority. - You can list multiple ranges in a single pool, they will all share the - same settings. Each range can be either a CIDR prefix, or an explicit - start-end range of IPs. - items: - type: string - type: array - autoAssign: - default: true - description: |- - AutoAssign flag used to prevent MetallB from automatic allocation - for a pool. - type: boolean - avoidBuggyIPs: - default: false - description: |- - AvoidBuggyIPs prevents addresses ending with .0 and .255 - to be used by a pool. - type: boolean - serviceAllocation: - description: |- - AllocateTo makes ip pool allocation to specific namespace and/or service. - The controller will use the pool with lowest value of priority in case of - multiple matches. A pool with no priority set will be used only if the - pools with priority can't be used. If multiple matching IPAddressPools are - available it will check for the availability of IPs sorting the matching - IPAddressPools by priority, starting from the highest to the lowest. If - multiple IPAddressPools have the same priority, choice will be random. - properties: - namespaceSelectors: - description: |- - NamespaceSelectors list of label selectors to select namespace(s) for ip pool, - an alternative to using namespace list. - items: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: array - namespaces: - description: Namespaces list of namespace(s) on which ip pool can be attached. - items: - type: string - type: array - priority: - description: Priority priority given for ip pool while ip allocation on a service. - type: integer - serviceSelectors: - description: |- - ServiceSelectors list of label selector to select service(s) for which ip pool - can be used for ip allocation. - items: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: array - type: object - required: - - addresses - type: object - status: - description: IPAddressPoolStatus defines the observed state of IPAddressPool. - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: l2advertisements.metallb.io -spec: - group: metallb.io - names: - kind: L2Advertisement - listKind: L2AdvertisementList - plural: l2advertisements - singular: l2advertisement - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.ipAddressPools - name: IPAddressPools - type: string - - jsonPath: .spec.ipAddressPoolSelectors - name: IPAddressPool Selectors - type: string - - jsonPath: .spec.interfaces - name: Interfaces - type: string - - jsonPath: .spec.nodeSelectors - name: Node Selectors - priority: 10 - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - L2Advertisement allows to advertise the LoadBalancer IPs provided - by the selected pools via L2. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: L2AdvertisementSpec defines the desired state of L2Advertisement. - properties: - interfaces: - description: |- - A list of interfaces to announce from. The LB IP will be announced only from these interfaces. - If the field is not set, we advertise from all the interfaces on the host. - items: - type: string - type: array - ipAddressPoolSelectors: - description: |- - A selector for the IPAddressPools which would get advertised via this advertisement. - If no IPAddressPool is selected by this or by the list, the advertisement is applied to all the IPAddressPools. - items: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: array - ipAddressPools: - description: The list of IPAddressPools to advertise via this advertisement, selected by name. - items: - type: string - type: array - nodeSelectors: - description: NodeSelectors allows to limit the nodes to announce as next hops for the LoadBalancer IP. When empty, all the nodes having are announced as next hops. - items: - description: |- - A label selector is a label query over a set of resources. The result of matchLabels and - matchExpressions are ANDed. An empty label selector matches all objects. A null - label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: array - type: object - status: - description: L2AdvertisementStatus defines the observed state of L2Advertisement. - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: servicel2statuses.metallb.io -spec: - group: metallb.io - names: - kind: ServiceL2Status - listKind: ServiceL2StatusList - plural: servicel2statuses - singular: servicel2status - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .status.node - name: Allocated Node - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: ServiceL2Status reveals the actual traffic status of loadbalancer services in layer2 mode. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: ServiceL2StatusSpec defines the desired state of ServiceL2Status. - type: object - status: - description: MetalLBServiceL2Status defines the observed state of ServiceL2Status. - properties: - interfaces: - description: Interfaces indicates the interfaces that receive the directed traffic - items: - description: InterfaceInfo defines interface info of layer2 announcement. - properties: - name: - description: Name the name of network interface card - type: string - type: object - type: array - node: - description: Node indicates the node that receives the directed traffic - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/charts/metallb/metallb/charts/frr-k8s/.helmignore b/charts/metallb/metallb/charts/frr-k8s/.helmignore deleted file mode 100644 index 0e8a0eb36..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/charts/metallb/metallb/charts/frr-k8s/Chart.lock b/charts/metallb/metallb/charts/frr-k8s/Chart.lock deleted file mode 100644 index 490ad005a..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: crds - repository: "" - version: 0.0.11 -digest: sha256:d4f716be0c84de180654aad05ce63aa91826873eaec2dd18e0fb5d7842a9d527 -generated: "2024-04-04T14:08:46.064693384+02:00" diff --git a/charts/metallb/metallb/charts/frr-k8s/Chart.yaml b/charts/metallb/metallb/charts/frr-k8s/Chart.yaml deleted file mode 100644 index 656a4d1c4..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/Chart.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v2 -appVersion: v0.0.11 -dependencies: -- condition: crds.enabled - name: crds - repository: "" - version: 0.0.11 -description: A cloud native wrapper of FRR -home: https://metallb.universe.tf -icon: https://metallb.universe.tf/images/logo/metallb-white.png -kubeVersion: '>= 1.19.0-0' -name: frr-k8s -sources: -- https://github.com/metallb/frr-k8s -type: application -version: 0.0.11 diff --git a/charts/metallb/metallb/charts/frr-k8s/README.md b/charts/metallb/metallb/charts/frr-k8s/README.md deleted file mode 100644 index eedb0b707..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# frr-k8s - -![Version: 0.0.11](https://img.shields.io/badge/Version-0.0.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.0.11](https://img.shields.io/badge/AppVersion-v0.0.11-informational?style=flat-square) - -A cloud native wrapper of FRR - -**Homepage:** - -## Source Code - -* - -## Requirements - -Kubernetes: `>= 1.19.0-0` - -| Repository | Name | Version | -|------------|------|---------| -| | crds | 0.0.11 | - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| crds.enabled | bool | `true` | | -| crds.validationFailurePolicy | string | `"Fail"` | | -| frrk8s.affinity | object | `{}` | | -| frrk8s.alwaysBlock | string | `""` | | -| frrk8s.disableCertRotation | bool | `false` | | -| frrk8s.frr.image.pullPolicy | string | `nil` | | -| frrk8s.frr.image.repository | string | `"quay.io/frrouting/frr"` | | -| frrk8s.frr.image.tag | string | `"9.0.2"` | | -| frrk8s.frr.metricsBindAddress | string | `"127.0.0.1"` | | -| frrk8s.frr.metricsPort | int | `7573` | | -| frrk8s.frr.resources | object | `{}` | | -| frrk8s.frr.secureMetricsPort | int | `9141` | | -| frrk8s.frrMetrics.resources | object | `{}` | | -| frrk8s.healthPort | int | `8081` | | -| frrk8s.image.pullPolicy | string | `nil` | | -| frrk8s.image.repository | string | `"quay.io/metallb/frr-k8s"` | | -| frrk8s.image.tag | string | `nil` | | -| frrk8s.labels.app | string | `"frr-k8s"` | | -| frrk8s.livenessProbe.enabled | bool | `true` | | -| frrk8s.livenessProbe.failureThreshold | int | `3` | | -| frrk8s.livenessProbe.initialDelaySeconds | int | `10` | | -| frrk8s.livenessProbe.periodSeconds | int | `10` | | -| frrk8s.livenessProbe.successThreshold | int | `1` | | -| frrk8s.livenessProbe.timeoutSeconds | int | `1` | | -| frrk8s.logLevel | string | `"info"` | Controller log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none` | -| frrk8s.nodeSelector | object | `{}` | | -| frrk8s.podAnnotations | object | `{}` | | -| frrk8s.priorityClassName | string | `""` | | -| frrk8s.readinessProbe.enabled | bool | `true` | | -| frrk8s.readinessProbe.failureThreshold | int | `3` | | -| frrk8s.readinessProbe.initialDelaySeconds | int | `10` | | -| frrk8s.readinessProbe.periodSeconds | int | `10` | | -| frrk8s.readinessProbe.successThreshold | int | `1` | | -| frrk8s.readinessProbe.timeoutSeconds | int | `1` | | -| frrk8s.reloader.resources | object | `{}` | | -| frrk8s.resources | object | `{}` | | -| frrk8s.restartOnRotatorSecretRefresh | bool | `false` | | -| frrk8s.runtimeClassName | string | `""` | | -| frrk8s.serviceAccount.annotations | object | `{}` | | -| frrk8s.serviceAccount.create | bool | `true` | | -| frrk8s.serviceAccount.name | string | `""` | | -| frrk8s.startupProbe.enabled | bool | `true` | | -| frrk8s.startupProbe.failureThreshold | int | `30` | | -| frrk8s.startupProbe.periodSeconds | int | `5` | | -| frrk8s.tolerateMaster | bool | `true` | | -| frrk8s.tolerations | list | `[]` | | -| frrk8s.updateStrategy.type | string | `"RollingUpdate"` | | -| fullnameOverride | string | `""` | | -| nameOverride | string | `""` | | -| prometheus.metricsBindAddress | string | `"127.0.0.1"` | | -| prometheus.metricsPort | int | `7572` | | -| prometheus.metricsTLSSecret | string | `""` | | -| prometheus.namespace | string | `""` | | -| prometheus.rbacPrometheus | bool | `false` | | -| prometheus.rbacProxy.pullPolicy | string | `nil` | | -| prometheus.rbacProxy.repository | string | `"gcr.io/kubebuilder/kube-rbac-proxy"` | | -| prometheus.rbacProxy.tag | string | `"v0.12.0"` | | -| prometheus.scrapeAnnotations | bool | `false` | | -| prometheus.secureMetricsPort | int | `9140` | | -| prometheus.serviceAccount | string | `""` | | -| prometheus.serviceMonitor.additionalLabels | object | `{}` | | -| prometheus.serviceMonitor.annotations | object | `{}` | | -| prometheus.serviceMonitor.enabled | bool | `false` | | -| prometheus.serviceMonitor.interval | string | `nil` | | -| prometheus.serviceMonitor.jobLabel | string | `"app.kubernetes.io/name"` | | -| prometheus.serviceMonitor.metricRelabelings | list | `[]` | | -| prometheus.serviceMonitor.relabelings | list | `[]` | | -| prometheus.serviceMonitor.tlsConfig.insecureSkipVerify | bool | `true` | | -| rbac.create | bool | `true` | | - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0) diff --git a/charts/metallb/metallb/charts/frr-k8s/charts/crds/.helmignore b/charts/metallb/metallb/charts/frr-k8s/charts/crds/.helmignore deleted file mode 100644 index 0e8a0eb36..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/charts/crds/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# 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/charts/metallb/metallb/charts/frr-k8s/charts/crds/Chart.yaml b/charts/metallb/metallb/charts/frr-k8s/charts/crds/Chart.yaml deleted file mode 100644 index fb9e2a141..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/charts/crds/Chart.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v2 -appVersion: v0.0.11 -description: FRR K8s CRDs -home: https://metallb.universe.tf -icon: https://metallb.universe.tf/images/logo/metallb-white.png -name: crds -sources: -- https://github.com/metallb/frr-k8s -type: application -version: 0.0.11 diff --git a/charts/metallb/metallb/charts/frr-k8s/charts/crds/README.md b/charts/metallb/metallb/charts/frr-k8s/charts/crds/README.md deleted file mode 100644 index 65e636c6d..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/charts/crds/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# crds - -![Version: 0.0.0](https://img.shields.io/badge/Version-0.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.0.0](https://img.shields.io/badge/AppVersion-v0.0.0-informational?style=flat-square) - -FRR-K8s CRDs - -**Homepage:** - -## Source Code - -* - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0) diff --git a/charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrconfigurations.yaml b/charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrconfigurations.yaml deleted file mode 100644 index 9f83ce7f1..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrconfigurations.yaml +++ /dev/null @@ -1,424 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.11.3 - creationTimestamp: null - name: frrconfigurations.frrk8s.metallb.io -spec: - group: frrk8s.metallb.io - names: - kind: FRRConfiguration - listKind: FRRConfigurationList - plural: frrconfigurations - singular: frrconfiguration - scope: Namespaced - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: FRRConfiguration is a piece of FRR configuration. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: FRRConfigurationSpec defines the desired state of FRRConfiguration. - properties: - bgp: - description: BGP is the configuration related to the BGP protocol. - properties: - bfdProfiles: - description: BFDProfiles is the list of bfd profiles to be used - when configuring the neighbors. - items: - description: BFDProfile is the configuration related to the - BFD protocol associated to a BGP session. - properties: - detectMultiplier: - description: Configures the detection multiplier to determine - packet loss. The remote transmission interval will be - multiplied by this value to determine the connection loss - detection timer. - format: int32 - maximum: 255 - minimum: 2 - type: integer - echoInterval: - description: Configures the minimal echo receive transmission - interval that this system is capable of handling in milliseconds. - Defaults to 50ms - format: int32 - maximum: 60000 - minimum: 10 - type: integer - echoMode: - description: Enables or disables the echo transmission mode. - This mode is disabled by default, and not supported on - multi hops setups. - type: boolean - minimumTtl: - description: 'For multi hop sessions only: configure the - minimum expected TTL for an incoming BFD control packet.' - format: int32 - maximum: 254 - minimum: 1 - type: integer - name: - description: The name of the BFD Profile to be referenced - in other parts of the configuration. - type: string - passiveMode: - description: 'Mark session as passive: a passive session - will not attempt to start the connection and will wait - for control packets from peer before it begins replying.' - type: boolean - receiveInterval: - description: The minimum interval that this system is capable - of receiving control packets in milliseconds. Defaults - to 300ms. - format: int32 - maximum: 60000 - minimum: 10 - type: integer - transmitInterval: - description: The minimum transmission interval (less jitter) - that this system wants to use to send BFD control packets - in milliseconds. Defaults to 300ms - format: int32 - maximum: 60000 - minimum: 10 - type: integer - required: - - name - type: object - type: array - routers: - description: Routers is the list of routers we want FRR to configure - (one per VRF). - items: - description: Router represent a neighbor router we want FRR - to connect to. - properties: - asn: - description: ASN is the AS number to use for the local end - of the session. - format: int32 - maximum: 4294967295 - minimum: 0 - type: integer - id: - description: ID is the BGP router ID - type: string - neighbors: - description: Neighbors is the list of neighbors we want - to establish BGP sessions with. - items: - description: Neighbor represents a BGP Neighbor we want - FRR to connect to. - properties: - address: - description: Address is the IP address to establish - the session with. - type: string - asn: - description: ASN is the AS number to use for the local - end of the session. - format: int32 - maximum: 4294967295 - minimum: 0 - type: integer - bfdProfile: - description: BFDProfile is the name of the BFD Profile - to be used for the BFD session associated to the - BGP session. If not set, the BFD session won't be - set up. - type: string - connectTime: - description: Requested BGP connect time, controls - how long BGP waits between connection attempts to - a neighbor. - type: string - x-kubernetes-validations: - - message: connect time should be between 1 seconds - to 65535 - rule: duration(self).getSeconds() >= 1 && duration(self).getSeconds() - <= 65535 - - message: connect time should contain a whole number - of seconds - rule: duration(self).getMilliseconds() % 1000 == - 0 - disableMP: - default: false - description: To set if we want to disable MP BGP that - will separate IPv4 and IPv6 route exchanges into - distinct BGP sessions. - type: boolean - ebgpMultiHop: - description: EBGPMultiHop indicates if the BGPPeer - is multi-hops away. - type: boolean - holdTime: - description: HoldTime is the requested BGP hold time, - per RFC4271. Defaults to 180s. - type: string - keepaliveTime: - description: KeepaliveTime is the requested BGP keepalive - time, per RFC4271. Defaults to 60s. - type: string - password: - description: Password to be used for establishing - the BGP session. Password and PasswordSecret are - mutually exclusive. - type: string - passwordSecret: - description: PasswordSecret is name of the authentication - secret for the neighbor. the secret must be of type - "kubernetes.io/basic-auth", and created in the same - namespace as the frr-k8s daemon. The password is - stored in the secret as the key "password". Password - and PasswordSecret are mutually exclusive. - properties: - name: - description: name is unique within a namespace - to reference a secret resource. - type: string - namespace: - description: namespace defines the space within - which the secret name must be unique. - type: string - type: object - x-kubernetes-map-type: atomic - port: - description: Port is the port to dial when establishing - the session. Defaults to 179. - maximum: 16384 - minimum: 0 - type: integer - toAdvertise: - description: ToAdvertise represents the list of prefixes - to advertise to the given neighbor and the associated - properties. - properties: - allowed: - description: Allowed is is the list of prefixes - allowed to be propagated to this neighbor. They - must match the prefixes defined in the router. - properties: - mode: - default: filtered - description: Mode is the mode to use when - handling the prefixes. When set to "filtered", - only the prefixes in the given list will - be allowed. When set to "all", all the prefixes - configured on the router will be allowed. - enum: - - all - - filtered - type: string - prefixes: - items: - type: string - type: array - type: object - withCommunity: - description: PrefixesWithCommunity is a list of - prefixes that are associated to a bgp community - when being advertised. The prefixes associated - to a given local pref must be in the prefixes - allowed to be advertised. - items: - description: CommunityPrefixes is a list of - prefixes associated to a community. - properties: - community: - description: Community is the community - associated to the prefixes. - type: string - prefixes: - description: Prefixes is the list of prefixes - associated to the community. - format: cidr - items: - type: string - minItems: 1 - type: array - type: object - type: array - withLocalPref: - description: PrefixesWithLocalPref is a list of - prefixes that are associated to a local preference - when being advertised. The prefixes associated - to a given local pref must be in the prefixes - allowed to be advertised. - items: - description: LocalPrefPrefixes is a list of - prefixes associated to a local preference. - properties: - localPref: - description: LocalPref is the local preference - associated to the prefixes. - format: int32 - type: integer - prefixes: - description: Prefixes is the list of prefixes - associated to the local preference. - format: cidr - items: - type: string - minItems: 1 - type: array - type: object - type: array - type: object - toReceive: - description: ToReceive represents the list of prefixes - to receive from the given neighbor. - properties: - allowed: - description: Allowed is the list of prefixes allowed - to be received from this neighbor. - properties: - mode: - default: filtered - description: Mode is the mode to use when - handling the prefixes. When set to "filtered", - only the prefixes in the given list will - be allowed. When set to "all", all the prefixes - configured on the router will be allowed. - enum: - - all - - filtered - type: string - prefixes: - items: - description: PrefixSelector is a filter - of prefixes to receive. - properties: - ge: - description: The prefix length modifier. - This selector accepts any matching - prefix with length greater or equal - the given value. - format: int32 - maximum: 128 - minimum: 1 - type: integer - le: - description: The prefix length modifier. - This selector accepts any matching - prefix with length less or equal the - given value. - format: int32 - maximum: 128 - minimum: 1 - type: integer - prefix: - format: cidr - type: string - type: object - type: array - type: object - type: object - required: - - address - - asn - type: object - type: array - prefixes: - description: Prefixes is the list of prefixes we want to - advertise from this router instance. - items: - type: string - type: array - vrf: - description: VRF is the host vrf used to establish sessions - from this router. - type: string - required: - - asn - type: object - type: array - type: object - nodeSelector: - description: NodeSelector limits the nodes that will attempt to apply - this config. When specified, the configuration will be considered - only on nodes whose labels match the specified selectors. When it - is not specified all nodes will attempt to apply this config. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - raw: - description: Raw is a snippet of raw frr configuration that gets appended - to the one rendered translating the type safe API. - properties: - priority: - description: Priority is the order with this configuration is - appended to the bottom of the rendered configuration. A higher - value means the raw config is appended later in the configuration - file. - type: integer - rawConfig: - description: Config is a raw FRR configuration to be appended - to the configuration rendered via the k8s api. - type: string - type: object - type: object - status: - description: FRRConfigurationStatus defines the observed state of FRRConfiguration. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrnodestates.yaml b/charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrnodestates.yaml deleted file mode 100644 index b0d25c30d..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/charts/crds/templates/frrk8s.metallb.io_frrnodestates.yaml +++ /dev/null @@ -1,61 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.11.3 - creationTimestamp: null - name: frrnodestates.frrk8s.metallb.io -spec: - group: frrk8s.metallb.io - names: - kind: FRRNodeState - listKind: FRRNodeStateList - plural: frrnodestates - singular: frrnodestate - scope: Cluster - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: FRRNodeState exposes the status of the FRR instance running on - each node. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: FRRNodeStateSpec defines the desired state of FRRNodeState. - type: object - status: - description: FRRNodeStateStatus defines the observed state of FRRNodeState. - properties: - lastConversionResult: - description: LastConversionResult is the status of the last translation - between the `FRRConfiguration`s resources and FRR's configuration, - contains "success" or an error. - type: string - lastReloadResult: - description: LastReloadResult represents the status of the last configuration - update operation by FRR, contains "success" or an error. - type: string - runningConfig: - description: RunningConfig represents the current FRR running config, - which is the configuration the FRR instance is currently running - with. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/charts/metallb/metallb/charts/frr-k8s/templates/NOTES.txt b/charts/metallb/metallb/charts/frr-k8s/templates/NOTES.txt deleted file mode 100644 index 5b5b84a17..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/templates/NOTES.txt +++ /dev/null @@ -1,4 +0,0 @@ -FRR-k8s is now running in the cluster. - -Now you can configure it via its CRs. Please refer to the frr-k8s official docs -on how to use the CRs. diff --git a/charts/metallb/metallb/charts/frr-k8s/templates/_helpers.tpl b/charts/metallb/metallb/charts/frr-k8s/templates/_helpers.tpl deleted file mode 100644 index 4e35f6fc6..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/templates/_helpers.tpl +++ /dev/null @@ -1,63 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "frrk8s.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 "frrk8s.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 "frrk8s.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "frrk8s.labels" -}} -helm.sh/chart: {{ include "frrk8s.chart" . }} -{{ include "frrk8s.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "frrk8s.selectorLabels" -}} -app.kubernetes.io/name: {{ include "frrk8s.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the frrk8s service account to use -*/}} -{{- define "frrk8s.serviceAccountName" -}} -{{- if .Values.frrk8s.serviceAccount.create }} -{{- default (printf "%s-controller" (include "frrk8s.fullname" .)) .Values.frrk8s.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.frrk8s.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/charts/metallb/metallb/charts/frr-k8s/templates/controller.yaml b/charts/metallb/metallb/charts/frr-k8s/templates/controller.yaml deleted file mode 100644 index 76dfcef7d..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/templates/controller.yaml +++ /dev/null @@ -1,431 +0,0 @@ -# FRR expects to have these files owned by frr:frr on startup. -# Having them in a ConfigMap allows us to modify behaviors: for example enabling more daemons on startup. -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "frrk8s.fullname" . }}-frr-startup - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "frrk8s.labels" . | nindent 4 }} - app.kubernetes.io/component: frr-k8s -data: - daemons: | - # This file tells the frr package which daemons to start. - # - # Sample configurations for these daemons can be found in - # /usr/share/doc/frr/examples/. - # - # ATTENTION: - # - # When activating a daemon for the first time, a config file, even if it is - # empty, has to be present *and* be owned by the user and group "frr", else - # the daemon will not be started by /etc/init.d/frr. The permissions should - # be u=rw,g=r,o=. - # When using "vtysh" such a config file is also needed. It should be owned by - # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. - # - # The watchfrr and zebra daemons are always started. - # - bgpd=yes - ospfd=no - ospf6d=no - ripd=no - ripngd=no - isisd=no - pimd=no - ldpd=no - nhrpd=no - eigrpd=no - babeld=no - sharpd=no - pbrd=no - bfdd=yes - fabricd=no - vrrpd=no - - # - # If this option is set the /etc/init.d/frr script automatically loads - # the config via "vtysh -b" when the servers are started. - # Check /etc/pam.d/frr if you intend to use "vtysh"! - # - vtysh_enable=yes - zebra_options=" -A 127.0.0.1 -s 90000000" - bgpd_options=" -A 127.0.0.1 -p 0" - ospfd_options=" -A 127.0.0.1" - ospf6d_options=" -A ::1" - ripd_options=" -A 127.0.0.1" - ripngd_options=" -A ::1" - isisd_options=" -A 127.0.0.1" - pimd_options=" -A 127.0.0.1" - ldpd_options=" -A 127.0.0.1" - nhrpd_options=" -A 127.0.0.1" - eigrpd_options=" -A 127.0.0.1" - babeld_options=" -A 127.0.0.1" - sharpd_options=" -A 127.0.0.1" - pbrd_options=" -A 127.0.0.1" - staticd_options="-A 127.0.0.1" - bfdd_options=" -A 127.0.0.1" - fabricd_options="-A 127.0.0.1" - vrrpd_options=" -A 127.0.0.1" - - # configuration profile - # - #frr_profile="traditional" - #frr_profile="datacenter" - - # - # This is the maximum number of FD's that will be available. - # Upon startup this is read by the control files and ulimit - # is called. Uncomment and use a reasonable value for your - # setup if you are expecting a large number of peers in - # say BGP. - #MAX_FDS=1024 - - # The list of daemons to watch is automatically generated by the init script. - #watchfrr_options="" - - # for debugging purposes, you can specify a "wrap" command to start instead - # of starting the daemon directly, e.g. to use valgrind on ospfd: - # ospfd_wrap="/usr/bin/valgrind" - # or you can use "all_wrap" for all daemons, e.g. to use perf record: - # all_wrap="/usr/bin/perf record --call-graph -" - # the normal daemon command is added to this at the end. - vtysh.conf: |+ - service integrated-vtysh-config - frr.conf: |+ - ! This file gets overriden the first time the speaker renders a config. - ! So anything configured here is only temporary. - frr version 7.5.1 - frr defaults traditional - hostname Router - line vty - log file /etc/frr/frr.log informational ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: {{ template "frrk8s.fullname" . }} - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "frrk8s.labels" . | nindent 4 }} - app.kubernetes.io/component: frr-k8s - {{- range $key, $value := .Values.frrk8s.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - {{- if .Values.frrk8s.updateStrategy }} - updateStrategy: {{- toYaml .Values.frrk8s.updateStrategy | nindent 4 }} - {{- end }} - selector: - matchLabels: - {{- include "frrk8s.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: frr-k8s - template: - metadata: - labels: - {{- include "frrk8s.selectorLabels" . | nindent 8 }} - app.kubernetes.io/component: frr-k8s - {{- range $key, $value := .Values.frrk8s.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} - spec: - {{- if .Values.frrk8s.runtimeClassName }} - runtimeClassName: {{ .Values.frrk8s.runtimeClassName }} - {{- end }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ template "frrk8s.serviceAccountName" . }} - terminationGracePeriodSeconds: 0 - hostNetwork: true - volumes: - - name: frr-sockets - emptyDir: {} - - name: frr-startup - configMap: - name: {{ template "frrk8s.fullname" . }}-frr-startup - - name: frr-conf - emptyDir: {} - - name: reloader - emptyDir: {} - - name: metrics - emptyDir: {} - {{- if .Values.prometheus.metricsTLSSecret }} - - name: metrics-certs - secret: - secretName: {{ .Values.prometheus.metricsTLSSecret }} - {{- end }} - initContainers: - # Copies the initial config files with the right permissions to the shared volume. - - name: cp-frr-files - image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }} - securityContext: - runAsUser: 100 - runAsGroup: 101 - command: ["/bin/sh", "-c", "cp -rLf /tmp/frr/* /etc/frr/"] - volumeMounts: - - name: frr-startup - mountPath: /tmp/frr - - name: frr-conf - mountPath: /etc/frr - # Copies the reloader to the shared volume between the speaker and reloader. - - name: cp-reloader - image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }} - command: ["/bin/sh", "-c", "cp -f /frr-reloader.sh /etc/frr_reloader/"] - volumeMounts: - - name: reloader - mountPath: /etc/frr_reloader - # Copies the metrics exporter - - name: cp-metrics - image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }} - command: ["/bin/sh", "-c", "cp -f /frr-metrics /etc/frr_metrics/"] - volumeMounts: - - name: metrics - mountPath: /etc/frr_metrics - shareProcessNamespace: true - containers: - - name: controller - image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }} - {{- if .Values.frrk8s.image.pullPolicy }} - imagePullPolicy: {{ .Values.frrk8s.image.pullPolicy }} - {{- end }} - command: - - /frr-k8s - args: - - "--node-name=$(NODE_NAME)" - - "--namespace=$(NAMESPACE)" - - "--metrics-bind-address={{.Values.prometheus.metricsBindAddress}}:{{ .Values.prometheus.metricsPort }}" - {{- with .Values.frrk8s.logLevel }} - - --log-level={{ . }} - {{- end }} - - --health-probe-bind-address={{.Values.prometheus.metricsBindAddress}}:{{ .Values.frrk8s.healthPort }} - {{- if .Values.frrk8s.alwaysBlock }} - - --always-block={{ .Values.frrk8s.alwaysBlock }} - {{- end }} - env: - - name: FRR_CONFIG_FILE - value: /etc/frr_reloader/frr.conf - - name: FRR_RELOADER_PID_FILE - value: /etc/frr_reloader/reloader.pid - - name: NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - ports: - - containerPort: {{ .Values.prometheus.metricsPort }} - name: monitoring - {{- if .Values.frrk8s.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: /healthz - port: {{ .Values.frrk8s.healthPort }} - host: {{ .Values.prometheus.metricsBindAddress }} - initialDelaySeconds: {{ .Values.frrk8s.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.frrk8s.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.frrk8s.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.frrk8s.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.frrk8s.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.frrk8s.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: /healthz - port: {{ .Values.frrk8s.healthPort }} - host: {{ .Values.prometheus.metricsBindAddress }} - initialDelaySeconds: {{ .Values.frrk8s.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.frrk8s.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.frrk8s.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.frrk8s.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.frrk8s.readinessProbe.failureThreshold }} - {{- end }} - {{- with .Values.frrk8s.resources }} - resources: - {{- toYaml . | nindent 10 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - add: - - NET_RAW - volumeMounts: - - name: reloader - mountPath: /etc/frr_reloader - - name: frr - securityContext: - capabilities: - add: - - NET_ADMIN - - NET_RAW - - SYS_ADMIN - - NET_BIND_SERVICE - image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }} - {{- if .Values.frrk8s.frr.image.pullPolicy }} - imagePullPolicy: {{ .Values.frrk8s.frr.image.pullPolicy }} - {{- end }} - env: - - name: TINI_SUBREAPER - value: "true" - volumeMounts: - - name: frr-sockets - mountPath: /var/run/frr - - name: frr-conf - mountPath: /etc/frr - # The command is FRR's default entrypoint & waiting for the log file to appear and tailing it. - # If the log file isn't created in 60 seconds the tail fails and the container is restarted. - # This workaround is needed to have the frr logs as part of kubectl logs -c frr < controller_pod_name >. - command: - - /bin/sh - - -c - - | - /sbin/tini -- /usr/lib/frr/docker-start & - attempts=0 - until [[ -f /etc/frr/frr.log || $attempts -eq 60 ]]; do - sleep 1 - attempts=$(( $attempts + 1 )) - done - tail -f /etc/frr/frr.log - {{- with .Values.frrk8s.frr.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- if .Values.frrk8s.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: /livez - port: {{ .Values.frrk8s.frr.metricsPort }} - host: {{ .Values.frrk8s.frr.metricsBindAddress }} - periodSeconds: {{ .Values.frrk8s.livenessProbe.periodSeconds }} - failureThreshold: {{ .Values.frrk8s.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.frrk8s.startupProbe.enabled }} - startupProbe: - httpGet: - path: /livez - port: {{ .Values.frrk8s.frr.metricsPort }} - host: {{ .Values.frrk8s.frr.metricsBindAddress }} - failureThreshold: {{ .Values.frrk8s.startupProbe.failureThreshold }} - periodSeconds: {{ .Values.frrk8s.startupProbe.periodSeconds }} - {{- end }} - - name: reloader - image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }} - {{- if .Values.frrk8s.frr.image.pullPolicy }} - imagePullPolicy: {{ .Values.frrk8s.frr.image.pullPolicy }} - {{- end }} - command: ["/etc/frr_reloader/frr-reloader.sh"] - volumeMounts: - - name: frr-sockets - mountPath: /var/run/frr - - name: frr-conf - mountPath: /etc/frr - - name: reloader - mountPath: /etc/frr_reloader - {{- with .Values.frrk8s.reloader.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - - name: frr-metrics - image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }} - command: ["/etc/frr_metrics/frr-metrics"] - args: - - --metrics-port={{ .Values.frrk8s.frr.metricsPort }} - - --metrics-bind-address={{ .Values.frrk8s.frr.metricsBindAddress }} - ports: - - containerPort: {{ .Values.frrk8s.frr.metricsPort }} - name: monitoring - volumeMounts: - - name: frr-sockets - mountPath: /var/run/frr - - name: frr-conf - mountPath: /etc/frr - - name: metrics - mountPath: /etc/frr_metrics - {{- with .Values.frrk8s.frrMetrics.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - - name: kube-rbac-proxy - image: {{ .Values.prometheus.rbacProxy.repository }}:{{ .Values.prometheus.rbacProxy.tag }} - imagePullPolicy: {{ .Values.prometheus.rbacProxy.pullPolicy }} - args: - - --logtostderr - - --secure-listen-address=:{{ .Values.prometheus.secureMetricsPort }} - - --upstream=http://{{.Values.prometheus.metricsBindAddress}}:{{ .Values.prometheus.metricsPort }}/ - - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - {{- if .Values.prometheus.metricsTLSSecret }} - - --tls-private-key-file=/etc/metrics/tls.key - - --tls-cert-file=/etc/metrics/tls.crt - {{- end }} - ports: - - containerPort: {{ .Values.prometheus.secureMetricsPort }} - name: metricshttps - resources: - requests: - cpu: 10m - memory: 20Mi - terminationMessagePolicy: FallbackToLogsOnError - {{- if .Values.prometheus.metricsTLSSecret }} - volumeMounts: - - name: metrics-certs - mountPath: /etc/metrics - readOnly: true - {{- end }} - - name: kube-rbac-proxy-frr - image: {{ .Values.prometheus.rbacProxy.repository }}:{{ .Values.prometheus.rbacProxy.tag | default .Chart.AppVersion }} - imagePullPolicy: {{ .Values.prometheus.rbacProxy.pullPolicy }} - args: - - --logtostderr - - --secure-listen-address=:{{ .Values.frrk8s.frr.secureMetricsPort }} - - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - - --upstream=http://{{ .Values.frrk8s.frr.metricsBindAddress }}:{{ .Values.frrk8s.frr.metricsPort }}/ - {{- if .Values.prometheus.metricsTLSSecret }} - - --tls-private-key-file=/etc/metrics/tls.key - - --tls-cert-file=/etc/metrics/tls.crt - {{- end }} - ports: - - containerPort: {{ .Values.frrk8s.frr.secureMetricsPort }} - name: metricshttps - resources: - requests: - cpu: 10m - memory: 20Mi - terminationMessagePolicy: FallbackToLogsOnError - {{- if .Values.prometheus.metricsTLSSecret }} - volumeMounts: - - name: metrics-certs - mountPath: /etc/metrics - readOnly: true - {{- end }} - nodeSelector: - "kubernetes.io/os": linux - {{- with .Values.frrk8s.nodeSelector }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.frrk8s.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if or .Values.frrk8s.tolerateMaster .Values.frrk8s.tolerations }} - tolerations: - {{- if .Values.frrk8s.tolerateMaster }} - - key: node-role.kubernetes.io/master - effect: NoSchedule - operator: Exists - - key: node-role.kubernetes.io/control-plane - effect: NoSchedule - operator: Exists - {{- end }} - {{- with .Values.frrk8s.tolerations }} - {{- toYaml . | nindent 6 }} - {{- end }} - {{- end }} - {{- with .Values.frrk8s.priorityClassName }} - priorityClassName: {{ . | quote }} - {{- end }} diff --git a/charts/metallb/metallb/charts/frr-k8s/templates/rbac.yaml b/charts/metallb/metallb/charts/frr-k8s/templates/rbac.yaml deleted file mode 100644 index e9beef897..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/templates/rbac.yaml +++ /dev/null @@ -1,73 +0,0 @@ -{{- if .Values.rbac.create -}} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ include "frrk8s.fullname" . }}-controller - labels: {{- include "frrk8s.labels" . | nindent 4 }} -rules: -- apiGroups: ["frrk8s.metallb.io"] - resources: ["frrconfigurations"] - verbs: ["get", "list", "watch"] -- apiGroups: ["frrk8s.metallb.io"] - resources: ["frrnodestates"] - verbs: ["get", "list", "watch", "create", "delete", "patch", "update"] -- apiGroups: ["frrk8s.metallb.io"] - resources: ["frrnodestates/status"] - verbs: ["get", "patch", "update"] -- apiGroups: [""] - resources: ["nodes"] - verbs: ["get", "list", "watch"] -- apiGroups: ["authentication.k8s.io"] - resources: ["tokenreviews"] - verbs: ["create"] -- apiGroups: ["authorization.k8s.io"] - resources: ["subjectaccessreviews"] - verbs: ["create"] -- apiGroups: ["admissionregistration.k8s.io"] - resources: ["validatingwebhookconfigurations"] - verbs: ["get", "list", "watch"] -- apiGroups: ["admissionregistration.k8s.io"] - resourceNames: ["frr-k8s-validating-webhook-configuration"] - resources: ["validatingwebhookconfigurations"] - verbs: ["update"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ include "frrk8s.fullname" . }}-controller - labels: {{- include "frrk8s.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ include "frrk8s.fullname" . }}-controller -subjects: -- kind: ServiceAccount - name: {{ include "frrk8s.serviceAccountName" . }} - namespace: {{ .Release.Namespace | quote }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ include "frrk8s.fullname" . }}-controller - namespace: {{ .Release.Namespace | quote }} - labels: {{- include "frrk8s.labels" . | nindent 4 }} -rules: -- apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list", "watch","update"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ include "frrk8s.fullname" . }}-controller - namespace: {{ .Release.Namespace | quote }} - labels: {{- include "frrk8s.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ include "frrk8s.fullname" . }}-controller -subjects: -- kind: ServiceAccount - name: {{ include "frrk8s.serviceAccountName" . }} -{{ end -}} diff --git a/charts/metallb/metallb/charts/frr-k8s/templates/service-accounts.yaml b/charts/metallb/metallb/charts/frr-k8s/templates/service-accounts.yaml deleted file mode 100644 index 3c64c5cb2..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/templates/service-accounts.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.frrk8s.serviceAccount.create }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "frrk8s.serviceAccountName" . }} - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "frrk8s.labels" . | nindent 4 }} - app.kubernetes.io/component: controller - {{- with .Values.frrk8s.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} - diff --git a/charts/metallb/metallb/charts/frr-k8s/templates/service-monitor.yaml b/charts/metallb/metallb/charts/frr-k8s/templates/service-monitor.yaml deleted file mode 100644 index c6f91304e..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/templates/service-monitor.yaml +++ /dev/null @@ -1,128 +0,0 @@ -{{- if .Values.prometheus.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "frrk8s.labels" . | nindent 4 }} - app.kubernetes.io/component: frr-k8s - {{- if .Values.prometheus.serviceMonitor.additionalLabels }} -{{ toYaml .Values.prometheus.serviceMonitor.additionalLabels | indent 4 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.annotations }} - annotations: -{{ toYaml .Values.prometheus.serviceMonitor.annotations | indent 4 }} - {{- end }} -spec: - endpoints: - - port: "metricshttps" - honorLabels: true - {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} - metricRelabelings: - {{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }} - {{- end -}} - {{- if .Values.prometheus.serviceMonitor.relabelings }} - relabelings: - {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.interval }} - interval: {{ .Values.prometheus.serviceMonitor.interval }} - {{- end -}} -{{ if .Values.prometheus.secureMetricsPort }} - bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token" - scheme: "https" -{{- if .Values.prometheus.serviceMonitor.tlsConfig }} - tlsConfig: -{{ toYaml .Values.prometheus.serviceMonitor.tlsConfig | indent 8 }} -{{- end }} -{{ end }} -{{ if .Values.frrk8s.frr.secureMetricsPort }} - - port: "frrmetricshttps" - honorLabels: true - {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} - metricRelabelings: - {{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }} - {{- end -}} - {{- if .Values.prometheus.serviceMonitor.relabelings }} - relabelings: - {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.interval }} - interval: {{ .Values.prometheus.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token" - scheme: "https" -{{- if .Values.prometheus.serviceMonitor.tlsConfig }} - tlsConfig: -{{ toYaml .Values.prometheus.serviceMonitor.tlsConfig | indent 8 }} -{{- end }} -{{- end }} - jobLabel: {{ .Values.prometheus.serviceMonitor.jobLabel | quote }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} - selector: - matchLabels: - name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor-service ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - prometheus.io/scrape: "true" - {{- if .Values.prometheus.serviceMonitor.annotations }} -{{ toYaml .Values.prometheus.serviceMonitor.annotations | indent 4 }} - {{- end }} - labels: - name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor-service - name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor-service - namespace: {{ .Release.Namespace | quote }} -spec: - selector: - {{- include "frrk8s.selectorLabels" . | nindent 4 }} - app.kubernetes.io/component: frr-k8s - clusterIP: None - ports: - - name: "metricshttps" - port: {{ .Values.prometheus.secureMetricsPort }} - targetPort: {{ .Values.prometheus.secureMetricsPort }} - - name: frrmetricshttps - port: {{ .Values.frrk8s.frr.secureMetricsPort }} - targetPort: {{ .Values.frrk8s.frr.secureMetricsPort }} - sessionAffinity: None - type: ClusterIP ---- -{{- if .Values.prometheus.rbacPrometheus }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "frrk8s.fullname" . }}-prometheus - namespace: {{ .Release.Namespace | quote }} -rules: - - apiGroups: - - "" - resources: - - pods - - services - - endpoints - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "frrk8s.fullname" . }}-prometheus - namespace: {{ .Release.Namespace | quote }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "frrk8s.fullname" . }}-prometheus -subjects: - - kind: ServiceAccount - name: {{ required ".Values.prometheus.serviceAccount must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.serviceAccount }} - namespace: {{ required ".Values.prometheus.namespace must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.namespace }} -{{- end }} -{{- end }} diff --git a/charts/metallb/metallb/charts/frr-k8s/templates/webhooks.yaml b/charts/metallb/metallb/charts/frr-k8s/templates/webhooks.yaml deleted file mode 100644 index 3a4b9cd14..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/templates/webhooks.yaml +++ /dev/null @@ -1,159 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "frrk8s.fullname" . }}-webhook-server - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "frrk8s.labels" . | nindent 4 }} - app.kubernetes.io/component: frr-k8s-webhook-server - {{- range $key, $value := .Values.frrk8s.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - selector: - matchLabels: - app.kubernetes.io/component: frr-k8s-webhook-server - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: frr-k8s-webhook-server - labels: - app.kubernetes.io/component: frr-k8s-webhook-server - spec: - {{- if .Values.frrk8s.runtimeClassName }} - runtimeClassName: {{ .Values.frrk8s.runtimeClassName }} - {{- end }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - containers: - - command: - - /frr-k8s - args: - {{- with .Values.frrk8s.logLevel }} - - --log-level={{ . }} - {{- end }} - - "--webhook-mode=onlywebhook" - {{- if .Values.frrk8s.disableCertRotation }} - - "--disable-cert-rotation=true" - {{- end }} - {{- if .Values.frrk8s.restartOnRotatorSecretRefresh }} - - "--restart-on-rotator-secret-refresh=true" - {{- end }} - - "--namespace=$(NAMESPACE)" - - --health-probe-bind-address=:8081 - env: - - name: NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }} - {{- if .Values.frrk8s.image.pullPolicy }} - imagePullPolicy: {{ .Values.frrk8s.image.pullPolicy }} - {{- end }} - name: frr-k8s-webhook-server - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - {{- if .Values.frrk8s.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: {{ .Values.frrk8s.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.frrk8s.livenessProbe.periodSeconds }} - failureThreshold: {{ .Values.frrk8s.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.frrk8s.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: {{ .Values.frrk8s.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.frrk8s.readinessProbe.periodSeconds }} - failureThreshold: {{ .Values.frrk8s.readinessProbe.failureThreshold }} - {{- end }} - {{- with .Values.frrk8s.resources }} - resources: - {{- toYaml . | nindent 10 }} - {{- end }} - volumeMounts: - - name: cert - mountPath: /tmp/k8s-webhook-server/serving-certs - readOnly: true - {{- with .Values.frrk8s.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if or .Values.frrk8s.tolerateMaster .Values.frrk8s.tolerations }} - tolerations: - {{- if .Values.frrk8s.tolerateMaster }} - - key: node-role.kubernetes.io/master - effect: NoSchedule - operator: Exists - - key: node-role.kubernetes.io/control-plane - effect: NoSchedule - operator: Exists - {{- end }} - {{- with .Values.frrk8s.tolerations }} - {{- toYaml . | nindent 6 }} - {{- end }} - {{- end }} - {{- with .Values.frrk8s.priorityClassName }} - priorityClassName: {{ . | quote }} - {{- end }} - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: frr-k8s-webhook-server-cert - serviceAccountName: {{ template "frrk8s.serviceAccountName" . }} - terminationGracePeriodSeconds: 10 ---- -apiVersion: v1 -kind: Secret -metadata: - name: frr-k8s-webhook-server-cert - namespace: {{ .Release.Namespace | quote }} ---- -apiVersion: v1 -kind: Service -metadata: - name: frr-k8s-webhook-service - namespace: {{ .Release.Namespace | quote }} -spec: - ports: - - port: 443 - targetPort: 9443 - selector: - app.kubernetes.io/component: frr-k8s-webhook-server ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: frr-k8s-validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: frr-k8s-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-frrk8s-metallb-io-v1beta1-frrconfiguration - failurePolicy: {{ .Values.crds.validationFailurePolicy }} - name: frrconfigurationsvalidationwebhook.metallb.io - rules: - - apiGroups: - - frrk8s.metallb.io - apiVersions: - - v1beta1 - operations: - - CREATE - - UPDATE - resources: - - frrconfigurations - sideEffects: None diff --git a/charts/metallb/metallb/charts/frr-k8s/values.schema.json b/charts/metallb/metallb/charts/frr-k8s/values.schema.json deleted file mode 100644 index cb7b914c7..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/values.schema.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft-07/schema#", - "title": "Values", - "type": "object", - "definitions": { - "prometheusAlert": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "labels": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - }, - "required": [ - "enabled" - ] - }, - "probe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - }, - "required": [ - "failureThreshold", - "initialDelaySeconds", - "periodSeconds", - "successThreshold", - "timeoutSeconds" - ] - }, - "component": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "logLevel": { - "type": "string", - "enum": [ - "all", - "debug", - "info", - "warn", - "error", - "none" - ] - }, - "image": { - "type": "object", - "properties": { - "repository": { - "type": "string" - }, - "tag": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "pullPolicy": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "string", - "enum": [ - "Always", - "IfNotPresent", - "Never" - ] - } - ] - } - } - }, - "serviceAccount": { - "type": "object", - "properties": { - "create": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "annotations": { - "type": "object" - } - } - }, - "resources": { - "type": "object" - }, - "nodeSelector": { - "type": "object" - }, - "tolerations": { - "type": "array", - "items": { - "type": "object" - } - }, - "priorityClassName": { - "type": "string" - }, - "runtimeClassName": { - "type": "string" - }, - "affinity": { - "type": "object" - }, - "podAnnotations": { - "type": "object" - }, - "livenessProbe": { - "$ref": "#/definitions/probe" - }, - "readinessProbe": { - "$ref": "#/definitions/probe" - } - }, - "required": [ - "image", - "serviceAccount" - ] - } - }, - "properties": { - "imagePullSecrets": { - "description": "Secrets used for pulling images", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - }, - "required": [ - "name" - ], - "additionalProperties": false - } - }, - "nameOverride": { - "description": "Override chart name", - "type": "string" - }, - "fullNameOverride": { - "description": "Override fully qualified app name", - "type": "string" - }, - "rbac": { - "description": "RBAC configuration", - "type": "object", - "properties": { - "create": { - "description": "Enable RBAC", - "type": "boolean" - } - } - }, - "prometheus": { - "description": "Prometheus monitoring config", - "type": "object", - "properties": { - "scrapeAnnotations": { - "type": "boolean" - }, - "metricsPort": { - "type": "integer" - }, - "secureMetricsPort": { - "type": "integer" - }, - "rbacPrometheus": { - "type": "boolean" - }, - "serviceAccount": { - "type": "string" - }, - "namespace": { - "type": "string" - }, - "rbacProxy": { - "description": "kube-rbac-proxy configuration", - "type": "object", - "properties": { - "repository": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "serviceMonitor": { - "description": "Prometheus Operator ServiceMonitors", - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "jobLabel": { - "type": "string" - }, - "interval": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ] - }, - "metricRelabelings": { - "type": "array", - "items": { - "type": "object" - } - }, - "relabelings": { - "type": "array", - "items": { - "type": "object" - } - } - } - } - }, - "frrk8s": { - "allOf": [ - { - "$ref": "#/definitions/component" - }, - { - "description": "FRR-K8s controller", - "type": "object", - "properties": { - "tolerateMaster": { - "type": "boolean" - }, - "updateStrategy": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - }, - "required": [ - "type" - ] - }, - "runtimeClassName": { - "type": "string" - }, - "secretName": { - "type": "string" - }, - "frr": { - "description": "The FRR properties in the controller", - "type": "object", - "properties": { - "image": { - "$ref": "#/definitions/component/properties/image" - }, - "metricsPort": { - "type": "integer" - }, - "secureMetricsPort": { - "type": "integer" - }, - "resources:": { - "type": "object" - } - }, - "required": [ - "enabled" - ] - }, - "command": { - "type": "string" - }, - "reloader": { - "type": "object", - "properties": { - "resources": { - "type": "object" - } - } - }, - "frrMetrics": { - "type": "object", - "properties": { - "resources": { - "type": "object" - } - } - } - }, - "required": [ - "tolerateMaster" - ] - } - ] - }, - "crds": { - "description": "CRD configuration", - "type": "object", - "properties": { - "enabled": { - "description": "Enable CRDs", - "type": "boolean" - }, - "validationFailurePolicy": { - "description": "Failure policy to use with validating webhooks", - "type": "string", - "enum": [ - "Ignore", - "Fail" - ] - } - } - } - }, - "frrk8s": { - "allOf": [ - { - "$ref": "#/definitions/component" - }, - { - "description": "FRRk8s Controller", - "type": "object", - "properties": { - "strategy": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - }, - "required": [ - "type" - ] - }, - "command": { - "type": "string" - }, - "webhookMode": { - "type": "string" - } - } - } - ] - } - }, - "required": [ - "frrk8s" - ] -} \ No newline at end of file diff --git a/charts/metallb/metallb/charts/frr-k8s/values.yaml b/charts/metallb/metallb/charts/frr-k8s/values.yaml deleted file mode 100644 index 32d118b9c..000000000 --- a/charts/metallb/metallb/charts/frr-k8s/values.yaml +++ /dev/null @@ -1,173 +0,0 @@ -# Default values for frr-k8s. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -nameOverride: "" -fullnameOverride: "" - -rbac: - # create specifies whether to install and use RBAC rules. - create: true - -prometheus: - # scrape annotations specifies whether to add Prometheus metric - # auto-collection annotations to pods. See - # https://github.com/prometheus/prometheus/blob/release-2.1/documentation/examples/prometheus-kubernetes.yml - # for a corresponding Prometheus configuration. Alternatively, you - # may want to use the Prometheus Operator - # (https://github.com/coreos/prometheus-operator) for more powerful - # monitoring configuration. If you use the Prometheus operator, this - # can be left at false. - scrapeAnnotations: false - - # bind addr frr-k8s will use for metrics - metricsBindAddress: 127.0.0.1 - - # port frr-k8s will listen on for metrics - metricsPort: 7572 - - # if set, enables rbac proxy on frr-k8s to expose - # the metrics via tls. - secureMetricsPort: 9140 - - # the name of the secret to be mounted in the frr-k8s pod - # to expose the metrics securely. If not present, a self signed - # certificate to be used. - metricsTLSSecret: "" - - # prometheus doens't have the permission to scrape all namespaces so we give it permission to scrape metallb's one - rbacPrometheus: false - - # the service account used by prometheus - # required when " .Values.prometheus.rbacPrometheus == true " and " prometheus.serviceMonitor.enabled=true " - serviceAccount: "" - - # the namespace where prometheus is deployed - # required when " .Values.prometheus.rbacPrometheus == true " and " prometheus.serviceMonitor.enabled=true " - namespace: "" - - # the image to be used for the kuberbacproxy container - rbacProxy: - repository: gcr.io/kubebuilder/kube-rbac-proxy - tag: v0.12.0 - pullPolicy: - - # Prometheus Operator ServiceMonitors. - serviceMonitor: - # enable support for Prometheus Operator - enabled: false - - additionalLabels: {} - # optional additional annotations for the controller serviceMonitor - annotations: {} - # optional tls configuration for the controller serviceMonitor, in case - # secure metrics are enabled. - tlsConfig: - insecureSkipVerify: true - - # Job label for scrape target - jobLabel: "app.kubernetes.io/name" - - # Scrape interval. If not set, the Prometheus default scrape interval is used. - interval: - - # metric relabel configs to apply to samples before ingestion. - metricRelabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - # relabel configs to apply to samples before ingestion. - relabelings: [] - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # target_label: nodename - # replacement: $1 - # action: replace - -# controller contains configuration specific to the FRRK8s controller -# daemonset. -frrk8s: - # -- Controller log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none` - logLevel: info - tolerateMaster: true - image: - repository: quay.io/metallb/frr-k8s - tag: - pullPolicy: - ## @param controller.updateStrategy.type FRR-K8s controller daemonset strategy type - ## ref: https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/ - ## - updateStrategy: - ## StrategyType - ## Can be set to RollingUpdate or OnDelete - ## - type: RollingUpdate - serviceAccount: - # Specifies whether a ServiceAccount should be created - create: true - # The name of the ServiceAccount to use. If not set and create is - # true, a name is generated using the fullname template - name: "" - annotations: {} - ## Defines a secret name for the controller to generate a memberlist encryption secret - ## By default secretName: {{ "metallb.fullname" }}-memberlist - ## - # secretName: - resources: {} - # limits: - # cpu: 100m - # memory: 100Mi - nodeSelector: {} - tolerations: [] - priorityClassName: "" - affinity: {} - ## Selects which runtime class will be used by the pod. - runtimeClassName: "" - podAnnotations: {} - labels: - app: frr-k8s - healthPort: 8081 - livenessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - startupProbe: - enabled: true - failureThreshold: 30 - periodSeconds: 5 - ## A comma separated list of cidrs we want always to block for incoming routes - alwaysBlock: "" - ## Specifies whether the cert rotator works as part of the webhook. - disableCertRotation: false - ## Specifies whether the pod restarts when the rotator refreshes the cert secret. - ## Enabling this proved useful for the webhook's stability when it is redeployed multiple times in succession. - restartOnRotatorSecretRefresh: false - # frr contains configuration specific to the FRR container, - frr: - image: - repository: quay.io/frrouting/frr - tag: 9.0.2 - pullPolicy: - metricsBindAddress: 127.0.0.1 - metricsPort: 7573 - resources: {} - secureMetricsPort: 9141 - reloader: - resources: {} - frrMetrics: - resources: {} -crds: - enabled: true - validationFailurePolicy: Fail diff --git a/charts/metallb/metallb/policy/controller.rego b/charts/metallb/metallb/policy/controller.rego deleted file mode 100644 index b7a0ea1a0..000000000 --- a/charts/metallb/metallb/policy/controller.rego +++ /dev/null @@ -1,16 +0,0 @@ -package main - -# validate serviceAccountName -deny[msg] { - input.kind == "Deployment" - serviceAccountName := input.spec.template.spec.serviceAccountName - not serviceAccountName == "release-name-metallb-controller" - msg = sprintf("controller serviceAccountName '%s' does not match expected value", [serviceAccountName]) -} - -# validate node selector includes builtin when custom ones are provided -deny[msg] { - input.kind == "Deployment" - not input.spec.template.spec.nodeSelector["kubernetes.io/os"] == "linux" - msg = "controller nodeSelector does not include '\"kubernetes.io/os\": linux'" -} diff --git a/charts/metallb/metallb/policy/rbac.rego b/charts/metallb/metallb/policy/rbac.rego deleted file mode 100644 index 047345ebf..000000000 --- a/charts/metallb/metallb/policy/rbac.rego +++ /dev/null @@ -1,27 +0,0 @@ -package main - -# Validate PSP exists in ClusterRole :controller -deny[msg] { - input.kind == "ClusterRole" - input.metadata.name == "metallb:controller" - input.rules[3] == { - "apiGroups": ["policy"], - "resources": ["podsecuritypolicies"], - "resourceNames": ["metallb-controller"], - "verbs": ["use"] - } - msg = "ClusterRole metallb:controller does not include PSP rule" -} - -# Validate PSP exists in ClusterRole :speaker -deny[msg] { - input.kind == "ClusterRole" - input.metadata.name == "metallb:speaker" - input.rules[3] == { - "apiGroups": ["policy"], - "resources": ["podsecuritypolicies"], - "resourceNames": ["metallb-controller"], - "verbs": ["use"] - } - msg = "ClusterRole metallb:speaker does not include PSP rule" -} diff --git a/charts/metallb/metallb/policy/speaker.rego b/charts/metallb/metallb/policy/speaker.rego deleted file mode 100644 index 146a0373c..000000000 --- a/charts/metallb/metallb/policy/speaker.rego +++ /dev/null @@ -1,30 +0,0 @@ -package main - -# validate serviceAccountName -deny[msg] { - input.kind == "DaemonSet" - serviceAccountName := input.spec.template.spec.serviceAccountName - not serviceAccountName == "release-name-metallb-speaker" - msg = sprintf("speaker serviceAccountName '%s' does not match expected value", [serviceAccountName]) -} - -# validate METALLB_ML_SECRET_KEY (memberlist) -deny[msg] { - input.kind == "DaemonSet" - not input.spec.template.spec.containers[0].env[5].name == "METALLB_ML_SECRET_KEY_PATH" - msg = "speaker env does not contain METALLB_ML_SECRET_KEY_PATH at env[5]" -} - -# validate node selector includes builtin when custom ones are provided -deny[msg] { - input.kind == "DaemonSet" - not input.spec.template.spec.nodeSelector["kubernetes.io/os"] == "linux" - msg = "controller nodeSelector does not include '\"kubernetes.io/os\": linux'" -} - -# validate tolerations include the builtins when custom ones are provided -deny[msg] { - input.kind == "DaemonSet" - not input.spec.template.spec.tolerations[0] == { "key": "node-role.kubernetes.io/master", "effect": "NoSchedule", "operator": "Exists" } - msg = "controller tolerations does not include node-role.kubernetes.io/master:NoSchedule" -} diff --git a/charts/metallb/metallb/templates/NOTES.txt b/charts/metallb/metallb/templates/NOTES.txt deleted file mode 100644 index 23d1d5bc1..000000000 --- a/charts/metallb/metallb/templates/NOTES.txt +++ /dev/null @@ -1,4 +0,0 @@ -MetalLB is now running in the cluster. - -Now you can configure it via its CRs. Please refer to the metallb official docs -on how to use the CRs. diff --git a/charts/metallb/metallb/templates/_helpers.tpl b/charts/metallb/metallb/templates/_helpers.tpl deleted file mode 100644 index 53d9528d8..000000000 --- a/charts/metallb/metallb/templates/_helpers.tpl +++ /dev/null @@ -1,113 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "metallb.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 "metallb.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 "metallb.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "metallb.labels" -}} -helm.sh/chart: {{ include "metallb.chart" . }} -{{ include "metallb.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "metallb.selectorLabels" -}} -app.kubernetes.io/name: {{ include "metallb.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the controller service account to use -*/}} -{{- define "metallb.controller.serviceAccountName" -}} -{{- if .Values.controller.serviceAccount.create }} -{{- default (printf "%s-controller" (include "metallb.fullname" .)) .Values.controller.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.controller.serviceAccount.name }} -{{- end }} -{{- end }} - -{{/* -Create the name of the speaker service account to use -*/}} -{{- define "metallb.speaker.serviceAccountName" -}} -{{- if .Values.speaker.serviceAccount.create }} -{{- default (printf "%s-speaker" (include "metallb.fullname" .)) .Values.speaker.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.speaker.serviceAccount.name }} -{{- end }} -{{- end }} - -{{/* -Create the name of the settings Secret to use. -*/}} -{{- define "metallb.secretName" -}} - {{ default ( printf "%s-memberlist" (include "metallb.fullname" .)) .Values.speaker.secretName | trunc 63 | trimSuffix "-" }} -{{- end -}} - -{{- define "metrics.exposedportname" -}} -{{- if .Values.prometheus.secureMetricsPort -}} -"metricshttps" -{{- else -}} -"metrics" -{{- end -}} -{{- end -}} - -{{- define "metrics.exposedfrrportname" -}} -{{- if .Values.speaker.frr.secureMetricsPort -}} -"frrmetricshttps" -{{- else -}} -"frrmetrics" -{{- end }} -{{- end }} - -{{- define "metrics.exposedport" -}} -{{- if .Values.prometheus.secureMetricsPort -}} -{{ .Values.prometheus.secureMetricsPort }} -{{- else -}} -{{ .Values.prometheus.metricsPort }} -{{- end -}} -{{- end }} - -{{- define "metrics.exposedfrrport" -}} -{{- if .Values.speaker.frr.secureMetricsPort -}} -{{ .Values.speaker.frr.secureMetricsPort }} -{{- else -}} -{{ .Values.speaker.frr.metricsPort }} -{{- end }} -{{- end }} diff --git a/charts/metallb/metallb/templates/controller.yaml b/charts/metallb/metallb/templates/controller.yaml deleted file mode 100644 index d7d299e29..000000000 --- a/charts/metallb/metallb/templates/controller.yaml +++ /dev/null @@ -1,194 +0,0 @@ -{{- if .Values.controller.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "metallb.fullname" . }}-controller - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: controller - {{- range $key, $value := .Values.controller.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - {{- if .Values.controller.strategy }} - strategy: {{- toYaml .Values.controller.strategy | nindent 4 }} - {{- end }} - selector: - matchLabels: - {{- include "metallb.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: controller - template: - metadata: - {{- if or .Values.prometheus.scrapeAnnotations .Values.controller.podAnnotations }} - annotations: - {{- if .Values.prometheus.scrapeAnnotations }} - prometheus.io/scrape: "true" - prometheus.io/port: "{{ .Values.prometheus.metricsPort }}" - {{- end }} - {{- with .Values.controller.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - labels: - {{- include "metallb.selectorLabels" . | nindent 8 }} - app.kubernetes.io/component: controller - {{- range $key, $value := .Values.controller.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} - spec: - {{- with .Values.controller.runtimeClassName }} - runtimeClassName: {{ . | quote }} - {{- end }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ template "metallb.controller.serviceAccountName" . }} - terminationGracePeriodSeconds: 0 -{{- if .Values.controller.securityContext }} - securityContext: -{{ toYaml .Values.controller.securityContext | indent 8 }} -{{- end }} - containers: - - name: controller - image: {{ .Values.controller.image.repository }}:{{ .Values.controller.image.tag | default .Chart.AppVersion }} - {{- if .Values.controller.image.pullPolicy }} - imagePullPolicy: {{ .Values.controller.image.pullPolicy }} - {{- end }} - {{- if .Values.controller.command }} - command: - - {{ .Values.controller.command }} - {{- end }} - args: - - --port={{ .Values.prometheus.metricsPort }} - {{- with .Values.controller.logLevel }} - - --log-level={{ . }} - {{- end }} - {{- if .Values.loadBalancerClass }} - - --lb-class={{ .Values.loadBalancerClass }} - {{- end }} - {{- if .Values.controller.webhookMode }} - - --webhook-mode={{ .Values.controller.webhookMode }} - {{- end }} - {{- if .Values.controller.tlsMinVersion }} - - --tls-min-version={{ .Values.controller.tlsMinVersion }} - {{- end }} - {{- if .Values.controller.tlsCipherSuites }} - - --tls-cipher-suites={{ .Values.controller.tlsCipherSuites }} - {{- end }} - env: - {{- if and .Values.speaker.enabled .Values.speaker.memberlist.enabled }} - - name: METALLB_ML_SECRET_NAME - value: {{ include "metallb.secretName" . }} - - name: METALLB_DEPLOYMENT - value: {{ template "metallb.fullname" . }}-controller - {{- end }} - {{- if .Values.speaker.frr.enabled }} - - name: METALLB_BGP_TYPE - value: frr - {{- end }} - {{- if .Values.frrk8s.enabled }} - - name: METALLB_BGP_TYPE - value: frr-k8s - {{- end }} - ports: - - name: monitoring - containerPort: {{ .Values.prometheus.metricsPort }} - - containerPort: 9443 - name: webhook-server - protocol: TCP - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - {{- if .Values.controller.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: /metrics - port: monitoring - initialDelaySeconds: {{ .Values.controller.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.controller.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.controller.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.controller.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.controller.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.controller.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: /metrics - port: monitoring - initialDelaySeconds: {{ .Values.controller.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.controller.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.controller.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.controller.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.controller.readinessProbe.failureThreshold }} - {{- end }} - {{- with .Values.controller.resources }} - resources: - {{- toYaml . | nindent 10 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - {{- if .Values.prometheus.secureMetricsPort }} - - name: kube-rbac-proxy - image: {{ .Values.prometheus.rbacProxy.repository }}:{{ .Values.prometheus.rbacProxy.tag }} - imagePullPolicy: {{ .Values.prometheus.rbacProxy.pullPolicy }} - args: - - --logtostderr - - --secure-listen-address=:{{ .Values.prometheus.secureMetricsPort }} - - --upstream=http://127.0.0.1:{{ .Values.prometheus.metricsPort }}/ - - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - {{- if .Values.prometheus.controllerMetricsTLSSecret }} - - --tls-private-key-file=/etc/metrics/tls.key - - --tls-cert-file=/etc/metrics/tls.crt - {{- end }} - ports: - - containerPort: {{ .Values.prometheus.secureMetricsPort }} - name: metricshttps - resources: - requests: - cpu: 10m - memory: 20Mi - terminationMessagePolicy: FallbackToLogsOnError - {{- if .Values.prometheus.controllerMetricsTLSSecret }} - volumeMounts: - - name: metrics-certs - mountPath: /etc/metrics - readOnly: true - {{- end }} - {{ end }} - {{- if .Values.controller.extraContainers }} - {{- toYaml .Values.controller.extraContainers | nindent 6 }} - {{- end }} - nodeSelector: - "kubernetes.io/os": linux - {{- with .Values.controller.nodeSelector }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.controller.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.controller.tolerations }} - tolerations: - {{- toYaml . | nindent 6 }} - {{- end }} - {{- with .Values.controller.priorityClassName }} - priorityClassName: {{ . | quote }} - {{- end }} - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: metallb-webhook-cert - {{- if .Values.prometheus.controllerMetricsTLSSecret }} - - name: metrics-certs - secret: - secretName: {{ .Values.prometheus.controllerMetricsTLSSecret }} - {{- end }} -{{- end }} diff --git a/charts/metallb/metallb/templates/deprecated_configInline.yaml b/charts/metallb/metallb/templates/deprecated_configInline.yaml deleted file mode 100644 index 8a1a551cc..000000000 --- a/charts/metallb/metallb/templates/deprecated_configInline.yaml +++ /dev/null @@ -1,3 +0,0 @@ -{{- if .Values.configInline }} -{{- fail "Starting from v0.13.0 configInline is no longer supported. Please see https://metallb.universe.tf/#backward-compatibility" }} -{{- end }} diff --git a/charts/metallb/metallb/templates/exclude-l2-config.yaml b/charts/metallb/metallb/templates/exclude-l2-config.yaml deleted file mode 100644 index 932c2d62a..000000000 --- a/charts/metallb/metallb/templates/exclude-l2-config.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{- if and .Values.speaker.enabled .Values.speaker.excludeInterfaces.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: metallb-excludel2 - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} -data: - excludel2.yaml: | - announcedInterfacesToExclude: - - ^docker.* - - ^cbr.* - - ^dummy.* - - ^virbr.* - - ^lxcbr.* - - ^veth.* - - ^lo$ - - ^cali.* - - ^tunl.* - - ^flannel.* - - ^kube-ipvs.* - - ^cni.* - - ^nodelocaldns.* -{{- end }} \ No newline at end of file diff --git a/charts/metallb/metallb/templates/podmonitor.yaml b/charts/metallb/metallb/templates/podmonitor.yaml deleted file mode 100644 index 93a7fd699..000000000 --- a/charts/metallb/metallb/templates/podmonitor.yaml +++ /dev/null @@ -1,106 +0,0 @@ -{{- if .Values.prometheus.podMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: PodMonitor -metadata: - name: {{ template "metallb.fullname" . }}-controller - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: controller - {{- if .Values.prometheus.podMonitor.additionalLabels }} -{{ toYaml .Values.prometheus.podMonitor.additionalLabels | indent 4 }} - {{- end }} - {{- if .Values.prometheus.podMonitor.annotations }} - annotations: -{{ toYaml .Values.prometheus.podMonitor.annotations | indent 4 }} - {{- end }} -spec: - jobLabel: {{ .Values.prometheus.podMonitor.jobLabel | quote }} - selector: - matchLabels: - {{- include "metallb.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: controller - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} - podMetricsEndpoints: - - port: monitoring - path: /metrics - {{- if .Values.prometheus.podMonitor.interval }} - interval: {{ .Values.prometheus.podMonitor.interval }} - {{- end }} -{{- if .Values.prometheus.podMonitor.metricRelabelings }} - metricRelabelings: -{{- toYaml .Values.prometheus.podMonitor.metricRelabelings | nindent 4 }} -{{- end }} -{{- if .Values.prometheus.podMonitor.relabelings }} - relabelings: -{{- toYaml .Values.prometheus.podMonitor.relabelings | nindent 4 }} -{{- end }} ---- -apiVersion: monitoring.coreos.com/v1 -kind: PodMonitor -metadata: - name: {{ template "metallb.fullname" . }}-speaker - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: speaker - {{- if .Values.prometheus.podMonitor.additionalLabels }} -{{ toYaml .Values.prometheus.podMonitor.additionalLabels | indent 4 }} - {{- end }} - {{- if .Values.prometheus.podMonitor.annotations }} - annotations: -{{ toYaml .Values.prometheus.podMonitor.annotations | indent 4 }} - {{- end }} -spec: - jobLabel: {{ .Values.prometheus.podMonitor.jobLabel | quote }} - selector: - matchLabels: - {{- include "metallb.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: speaker - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} - podMetricsEndpoints: - - port: monitoring - path: /metrics - {{- if .Values.prometheus.podMonitor.interval }} - interval: {{ .Values.prometheus.podMonitor.interval }} - {{- end }} -{{- if .Values.prometheus.podMonitor.metricRelabelings }} - metricRelabelings: -{{- toYaml .Values.prometheus.podMonitor.metricRelabelings | nindent 4 }} -{{- end }} -{{- if .Values.prometheus.podMonitor.relabelings }} - relabelings: -{{- toYaml .Values.prometheus.podMonitor.relabelings | nindent 4 }} -{{- end }} ---- -{{- if .Values.prometheus.rbacPrometheus }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "metallb.fullname" . }}-prometheus -rules: - - apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "metallb.fullname" . }}-prometheus -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "metallb.fullname" . }}-prometheus -subjects: - - kind: ServiceAccount - name: {{ required ".Values.prometheus.serviceAccount must be defined when .Values.prometheus.podMonitor.enabled == true" .Values.prometheus.serviceAccount }} - namespace: {{ required ".Values.prometheus.namespace must be defined when .Values.prometheus.podMonitor.enabled == true" .Values.prometheus.namespace }} -{{- end }} -{{- end }} diff --git a/charts/metallb/metallb/templates/prometheusrules.yaml b/charts/metallb/metallb/templates/prometheusrules.yaml deleted file mode 100644 index 463aacafb..000000000 --- a/charts/metallb/metallb/templates/prometheusrules.yaml +++ /dev/null @@ -1,84 +0,0 @@ -{{- if .Values.prometheus.prometheusRule.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: {{ template "metallb.fullname" . }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - {{- if .Values.prometheus.prometheusRule.additionalLabels }} -{{ toYaml .Values.prometheus.prometheusRule.additionalLabels | indent 4 }} - {{- end }} - {{- if .Values.prometheus.prometheusRule.annotations }} - annotations: -{{ toYaml .Values.prometheus.prometheusRule.annotations | indent 4 }} - {{- end }} -spec: - groups: - - name: {{ template "metallb.fullname" . }}.rules - rules: - {{- if .Values.prometheus.prometheusRule.staleConfig.enabled }} - - alert: MetalLBStaleConfig - annotations: - message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod - }} has a stale config for > 1 minute'`}} - expr: metallb_k8s_client_config_stale_bool{job="{{ include "metallb.name" . }}"} == 1 - for: 1m - {{- with .Values.prometheus.prometheusRule.staleConfig.labels }} - labels: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - {{- if .Values.prometheus.prometheusRule.configNotLoaded.enabled }} - - alert: MetalLBConfigNotLoaded - annotations: - message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod - }} has not loaded for > 1 minute'`}} - expr: metallb_k8s_client_config_loaded_bool{job="{{ include "metallb.name" . }}"} == 0 - for: 1m - {{- with .Values.prometheus.prometheusRule.configNotLoaded.labels }} - labels: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - {{- if .Values.prometheus.prometheusRule.addressPoolExhausted.enabled }} - - alert: MetalLBAddressPoolExhausted - annotations: - message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod - }} has exhausted address pool {{ $labels.pool }} for > 1 minute'`}} - expr: metallb_allocator_addresses_in_use_total >= on(pool) metallb_allocator_addresses_total - for: 1m - {{- with .Values.prometheus.prometheusRule.addressPoolExhausted.labels }} - labels: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - - {{- if .Values.prometheus.prometheusRule.addressPoolUsage.enabled }} - {{- range .Values.prometheus.prometheusRule.addressPoolUsage.thresholds }} - - alert: MetalLBAddressPoolUsage{{ .percent }}Percent - annotations: - message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod - }} has address pool {{ $labels.pool }} past `}}{{ .percent }}{{`% usage for > 1 minute'`}} - expr: ( metallb_allocator_addresses_in_use_total / on(pool) metallb_allocator_addresses_total ) * 100 > {{ .percent }} - {{- with .labels }} - labels: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - {{- end }} - {{- if .Values.prometheus.prometheusRule.bgpSessionDown.enabled }} - - alert: MetalLBBGPSessionDown - annotations: - message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod - }} has BGP session {{ $labels.peer }} down for > 1 minute'`}} - expr: metallb_bgp_session_up{job="{{ include "metallb.name" . }}"} == 0 - for: 1m - {{- with .Values.prometheus.prometheusRule.bgpSessionDown.labels }} - labels: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - {{- with .Values.prometheus.prometheusRule.extraAlerts }} - {{- toYaml . | nindent 4 }} - {{- end}} -{{- end }} diff --git a/charts/metallb/metallb/templates/rbac.yaml b/charts/metallb/metallb/templates/rbac.yaml deleted file mode 100644 index 914ff82af..000000000 --- a/charts/metallb/metallb/templates/rbac.yaml +++ /dev/null @@ -1,212 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "metallb.fullname" . }}:controller - labels: - {{- include "metallb.labels" . | nindent 4 }} -rules: -- apiGroups: [""] - resources: ["services", "namespaces"] - verbs: ["get", "list", "watch"] -- apiGroups: [""] - resources: ["nodes"] - verbs: ["list"] -- apiGroups: [""] - resources: ["services/status"] - verbs: ["update"] -- apiGroups: [""] - resources: ["events"] - verbs: ["create", "patch"] -- apiGroups: ["admissionregistration.k8s.io"] - resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] - resourceNames: ["metallb-webhook-configuration"] - verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] -- apiGroups: ["admissionregistration.k8s.io"] - resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] - verbs: ["list", "watch"] -- apiGroups: ["apiextensions.k8s.io"] - resources: ["customresourcedefinitions"] - resourceNames: ["bfdprofiles.metallb.io","bgpadvertisements.metallb.io", - "bgppeers.metallb.io","ipaddresspools.metallb.io","l2advertisements.metallb.io","communities.metallb.io"] - verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] -- apiGroups: ["apiextensions.k8s.io"] - resources: ["customresourcedefinitions"] - verbs: ["list", "watch"] -{{- if .Values.prometheus.secureMetricsPort }} -- apiGroups: ["authentication.k8s.io"] - resources: ["tokenreviews"] - verbs: ["create"] -- apiGroups: ["authorization.k8s.io"] - resources: ["subjectaccessreviews"] - verbs: ["create"] -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ template "metallb.fullname" . }}:speaker - labels: - {{- include "metallb.labels" . | nindent 4 }} -rules: -- apiGroups: [""] - resources: ["services", "endpoints", "nodes", "namespaces"] - verbs: ["get", "list", "watch"] -- apiGroups: ["discovery.k8s.io"] - resources: ["endpointslices"] - verbs: ["get", "list", "watch"] -- apiGroups: [""] - resources: ["events"] - verbs: ["create", "patch"] -- apiGroups: ["metallb.io"] - resources: ["servicel2statuses","servicel2statuses/status"] - verbs: ["*"] -{{- if .Values.prometheus.secureMetricsPort }} -- apiGroups: ["authentication.k8s.io"] - resources: ["tokenreviews"] - verbs: ["create"] -- apiGroups: ["authorization.k8s.io"] - resources: ["subjectaccessreviews"] - verbs: ["create"] -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ include "metallb.fullname" . }}-pod-lister - namespace: {{ .Release.Namespace | quote }} - labels: {{- include "metallb.labels" . | nindent 4 }} -rules: -- apiGroups: [""] - resources: ["pods"] - verbs: ["list"] -- apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list", "watch"] -- apiGroups: [""] - resources: ["configmaps"] - verbs: ["get", "list", "watch"] -- apiGroups: ["metallb.io"] - resources: ["bfdprofiles"] - verbs: ["get", "list", "watch"] -- apiGroups: ["metallb.io"] - resources: ["bgppeers"] - verbs: ["get", "list", "watch"] -- apiGroups: ["metallb.io"] - resources: ["l2advertisements"] - verbs: ["get", "list", "watch"] -- apiGroups: ["metallb.io"] - resources: ["bgpadvertisements"] - verbs: ["get", "list", "watch"] -- apiGroups: ["metallb.io"] - resources: ["ipaddresspools"] - verbs: ["get", "list", "watch"] -- apiGroups: ["metallb.io"] - resources: ["communities"] - verbs: ["get", "list", "watch"] -{{- if .Values.frrk8s.enabled }} -- apiGroups: ["frrk8s.metallb.io"] - resources: ["frrconfigurations"] - verbs: ["get", "list", "watch","create","update"] -{{- end }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ include "metallb.fullname" . }}-controller - namespace: {{ .Release.Namespace | quote }} - labels: {{- include "metallb.labels" . | nindent 4 }} -rules: -{{- if .Values.speaker.memberlist.enabled }} -- apiGroups: [""] - resources: ["secrets"] - verbs: ["create", "get", "list", "watch"] -- apiGroups: [""] - resources: ["secrets"] - resourceNames: [{{ include "metallb.secretName" . | quote }}] - verbs: ["list"] -- apiGroups: ["apps"] - resources: ["deployments"] - resourceNames: ["{{ template "metallb.fullname" . }}-controller"] - verbs: ["get"] -{{- end }} -- apiGroups: [""] - resources: ["secrets"] - verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] -- apiGroups: ["metallb.io"] - resources: ["ipaddresspools"] - verbs: ["get", "list", "watch"] -- apiGroups: ["metallb.io"] - resources: ["bgppeers"] - verbs: ["get", "list"] -- apiGroups: ["metallb.io"] - resources: ["bgpadvertisements"] - verbs: ["get", "list"] -- apiGroups: ["metallb.io"] - resources: ["l2advertisements"] - verbs: ["get", "list"] -- apiGroups: ["metallb.io"] - resources: ["communities"] - verbs: ["get", "list","watch"] -- apiGroups: ["metallb.io"] - resources: ["bfdprofiles"] - verbs: ["get", "list","watch"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "metallb.fullname" . }}:controller - labels: - {{- include "metallb.labels" . | nindent 4 }} -subjects: -- kind: ServiceAccount - name: {{ template "metallb.controller.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "metallb.fullname" . }}:controller ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ template "metallb.fullname" . }}:speaker - labels: - {{- include "metallb.labels" . | nindent 4 }} -subjects: -- kind: ServiceAccount - name: {{ template "metallb.speaker.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ template "metallb.fullname" . }}:speaker ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ include "metallb.fullname" . }}-pod-lister - namespace: {{ .Release.Namespace | quote }} - labels: {{- include "metallb.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ include "metallb.fullname" . }}-pod-lister -subjects: -- kind: ServiceAccount - name: {{ include "metallb.speaker.serviceAccountName" . }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ include "metallb.fullname" . }}-controller - namespace: {{ .Release.Namespace | quote }} - labels: {{- include "metallb.labels" . | nindent 4 }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ include "metallb.fullname" . }}-controller -subjects: -- kind: ServiceAccount - name: {{ include "metallb.controller.serviceAccountName" . }} -{{- end -}} diff --git a/charts/metallb/metallb/templates/service-accounts.yaml b/charts/metallb/metallb/templates/service-accounts.yaml deleted file mode 100644 index 9615acf34..000000000 --- a/charts/metallb/metallb/templates/service-accounts.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.controller.serviceAccount.create }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "metallb.controller.serviceAccountName" . }} - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: controller - {{- with .Values.controller.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} -{{- if .Values.speaker.serviceAccount.create }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ template "metallb.speaker.serviceAccountName" . }} - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: speaker - {{- with .Values.speaker.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/charts/metallb/metallb/templates/servicemonitor.yaml b/charts/metallb/metallb/templates/servicemonitor.yaml deleted file mode 100644 index 1cfc0c43b..000000000 --- a/charts/metallb/metallb/templates/servicemonitor.yaml +++ /dev/null @@ -1,193 +0,0 @@ -{{- if .Values.prometheus.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "metallb.fullname" . }}-speaker-monitor - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: speaker - {{- if .Values.prometheus.serviceMonitor.speaker.additionalLabels }} -{{ toYaml .Values.prometheus.serviceMonitor.speaker.additionalLabels | indent 4 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.speaker.annotations }} - annotations: -{{ toYaml .Values.prometheus.serviceMonitor.speaker.annotations | indent 4 }} - {{- end }} -spec: - endpoints: - - port: {{ template "metrics.exposedportname" . }} - honorLabels: true - {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} - metricRelabelings: - {{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }} - {{- end -}} - {{- if .Values.prometheus.serviceMonitor.relabelings }} - relabelings: - {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.interval }} - interval: {{ .Values.prometheus.serviceMonitor.interval }} - {{- end -}} -{{ if .Values.prometheus.secureMetricsPort }} - bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token" - scheme: "https" -{{- if .Values.prometheus.serviceMonitor.speaker.tlsConfig }} - tlsConfig: -{{ toYaml .Values.prometheus.serviceMonitor.speaker.tlsConfig | indent 8 }} -{{- end }} -{{ end }} -{{- if .Values.speaker.frr.enabled }} - - port: {{ template "metrics.exposedfrrportname" . }} - honorLabels: true -{{ if .Values.speaker.frr.secureMetricsPort }} - {{- if .Values.prometheus.serviceMonitor.interval }} - interval: {{ .Values.prometheus.serviceMonitor.interval }} - {{- end }} - bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token" - scheme: "https" -{{- if .Values.prometheus.serviceMonitor.speaker.tlsConfig }} - tlsConfig: -{{ toYaml .Values.prometheus.serviceMonitor.speaker.tlsConfig | indent 8 }} -{{- end }} -{{- end }} -{{- end }} - jobLabel: {{ .Values.prometheus.serviceMonitor.jobLabel | quote }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} - selector: - matchLabels: - name: {{ template "metallb.fullname" . }}-speaker-monitor-service ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - prometheus.io/scrape: "true" - {{- if .Values.prometheus.serviceMonitor.speaker.annotations }} -{{ toYaml .Values.prometheus.serviceMonitor.speaker.annotations | indent 4 }} - {{- end }} - labels: - name: {{ template "metallb.fullname" . }}-speaker-monitor-service - name: {{ template "metallb.fullname" . }}-speaker-monitor-service - namespace: {{ .Release.Namespace | quote }} -spec: - selector: - {{- include "metallb.selectorLabels" . | nindent 4 }} - app.kubernetes.io/component: speaker - clusterIP: None - ports: - - name: {{ template "metrics.exposedportname" . }} - port: {{ template "metrics.exposedport" . }} - targetPort: {{ template "metrics.exposedport" . }} -{{- if .Values.speaker.frr.enabled }} - - name: {{ template "metrics.exposedfrrportname" . }} - port: {{ template "metrics.exposedfrrport" . }} - targetPort: {{ template "metrics.exposedfrrport" . }} -{{- end }} - sessionAffinity: None - type: ClusterIP ---- -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ template "metallb.fullname" . }}-controller-monitor - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: speaker - {{- if .Values.prometheus.serviceMonitor.controller.additionalLabels }} -{{ toYaml .Values.prometheus.serviceMonitor.controller.additionalLabels | indent 4 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.controller.annotations }} - annotations: -{{ toYaml .Values.prometheus.serviceMonitor.controller.annotations | indent 4 }} - {{- end }} -spec: - endpoints: - - port: {{ template "metrics.exposedportname" . }} - {{- if .Values.prometheus.serviceMonitor.metricRelabelings }} - metricRelabelings: - {{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }} - {{- end -}} - {{- if .Values.prometheus.serviceMonitor.relabelings }} - relabelings: - {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }} - {{- end }} - {{- if .Values.prometheus.serviceMonitor.interval }} - interval: {{ .Values.prometheus.serviceMonitor.interval }} - {{- end }} - honorLabels: true -{{- if .Values.prometheus.secureMetricsPort }} - bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token" - scheme: "https" -{{- if .Values.prometheus.serviceMonitor.controller.tlsConfig }} - tlsConfig: -{{ toYaml .Values.prometheus.serviceMonitor.controller.tlsConfig | indent 8 }} -{{- end }} -{{- end }} - jobLabel: {{ .Values.prometheus.serviceMonitor.jobLabel | quote }} - namespaceSelector: - matchNames: - - {{ .Release.Namespace }} - selector: - matchLabels: - name: {{ template "metallb.fullname" . }}-controller-monitor-service ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - prometheus.io/scrape: "true" - {{- if .Values.prometheus.serviceMonitor.controller.annotations }} -{{ toYaml .Values.prometheus.serviceMonitor.controller.annotations | indent 4 }} - {{- end }} - labels: - name: {{ template "metallb.fullname" . }}-controller-monitor-service - name: {{ template "metallb.fullname" . }}-controller-monitor-service -spec: - selector: - {{- include "metallb.selectorLabels" . | nindent 4 }} - app.kubernetes.io/component: controller - clusterIP: None - ports: - - name: {{ template "metrics.exposedportname" . }} - port: {{ template "metrics.exposedport" . }} - targetPort: {{ template "metrics.exposedport" . }} - sessionAffinity: None - type: ClusterIP ---- -{{- if .Values.prometheus.rbacPrometheus }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ template "metallb.fullname" . }}-prometheus - namespace: {{ .Release.Namespace | quote }} -rules: - - apiGroups: - - "" - resources: - - pods - - services - - endpoints - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ template "metallb.fullname" . }}-prometheus - namespace: {{ .Release.Namespace | quote }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ template "metallb.fullname" . }}-prometheus -subjects: - - kind: ServiceAccount - name: {{ required ".Values.prometheus.serviceAccount must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.serviceAccount }} - namespace: {{ required ".Values.prometheus.namespace must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.namespace }} -{{- end }} -{{- end }} diff --git a/charts/metallb/metallb/templates/speaker.yaml b/charts/metallb/metallb/templates/speaker.yaml deleted file mode 100644 index ac7ee6298..000000000 --- a/charts/metallb/metallb/templates/speaker.yaml +++ /dev/null @@ -1,553 +0,0 @@ -{{- if .Values.speaker.frr.enabled }} -{{- if .Values.frrk8s.enabled }} -{{- fail "speaker.frr.enabled and frrk8s.enabled are mutually exclusive!" }} -{{- end }} -{{- end }} -{{- if .Values.speaker.frr.enabled }} - -# FRR expects to have these files owned by frr:frr on startup. -# Having them in a ConfigMap allows us to modify behaviors: for example enabling more daemons on startup. -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "metallb.fullname" . }}-frr-startup - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: speaker -data: - daemons: | - # This file tells the frr package which daemons to start. - # - # Sample configurations for these daemons can be found in - # /usr/share/doc/frr/examples/. - # - # ATTENTION: - # - # When activating a daemon for the first time, a config file, even if it is - # empty, has to be present *and* be owned by the user and group "frr", else - # the daemon will not be started by /etc/init.d/frr. The permissions should - # be u=rw,g=r,o=. - # When using "vtysh" such a config file is also needed. It should be owned by - # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. - # - # The watchfrr and zebra daemons are always started. - # - bgpd=yes - ospfd=no - ospf6d=no - ripd=no - ripngd=no - isisd=no - pimd=no - ldpd=no - nhrpd=no - eigrpd=no - babeld=no - sharpd=no - pbrd=no - bfdd=yes - fabricd=no - vrrpd=no - - # - # If this option is set the /etc/init.d/frr script automatically loads - # the config via "vtysh -b" when the servers are started. - # Check /etc/pam.d/frr if you intend to use "vtysh"! - # - vtysh_enable=yes - zebra_options=" -A 127.0.0.1 -s 90000000" - bgpd_options=" -A 127.0.0.1 -p 0" - ospfd_options=" -A 127.0.0.1" - ospf6d_options=" -A ::1" - ripd_options=" -A 127.0.0.1" - ripngd_options=" -A ::1" - isisd_options=" -A 127.0.0.1" - pimd_options=" -A 127.0.0.1" - ldpd_options=" -A 127.0.0.1" - nhrpd_options=" -A 127.0.0.1" - eigrpd_options=" -A 127.0.0.1" - babeld_options=" -A 127.0.0.1" - sharpd_options=" -A 127.0.0.1" - pbrd_options=" -A 127.0.0.1" - staticd_options="-A 127.0.0.1" - bfdd_options=" -A 127.0.0.1" - fabricd_options="-A 127.0.0.1" - vrrpd_options=" -A 127.0.0.1" - - # configuration profile - # - #frr_profile="traditional" - #frr_profile="datacenter" - - # - # This is the maximum number of FD's that will be available. - # Upon startup this is read by the control files and ulimit - # is called. Uncomment and use a reasonable value for your - # setup if you are expecting a large number of peers in - # say BGP. - #MAX_FDS=1024 - - # The list of daemons to watch is automatically generated by the init script. - #watchfrr_options="" - - # for debugging purposes, you can specify a "wrap" command to start instead - # of starting the daemon directly, e.g. to use valgrind on ospfd: - # ospfd_wrap="/usr/bin/valgrind" - # or you can use "all_wrap" for all daemons, e.g. to use perf record: - # all_wrap="/usr/bin/perf record --call-graph -" - # the normal daemon command is added to this at the end. - vtysh.conf: |+ - service integrated-vtysh-config - frr.conf: |+ - ! This file gets overriden the first time the speaker renders a config. - ! So anything configured here is only temporary. - frr version 7.5.1 - frr defaults traditional - hostname Router - line vty - log file /etc/frr/frr.log informational -{{- end }} ---- -{{- if .Values.speaker.enabled }} -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: {{ template "metallb.fullname" . }}-speaker - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} - app.kubernetes.io/component: speaker - {{- range $key, $value := .Values.speaker.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - {{- if .Values.speaker.updateStrategy }} - updateStrategy: {{- toYaml .Values.speaker.updateStrategy | nindent 4 }} - {{- end }} - selector: - matchLabels: - {{- include "metallb.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: speaker - template: - metadata: - {{- if or .Values.prometheus.scrapeAnnotations .Values.speaker.podAnnotations }} - annotations: - {{- if .Values.prometheus.scrapeAnnotations }} - prometheus.io/scrape: "true" - {{- if not .Values.speaker.frr.enabled }} - prometheus.io/port: "{{ .Values.prometheus.metricsPort }}" - {{- end }} - {{- end }} - {{- with .Values.speaker.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- end }} - labels: - {{- include "metallb.selectorLabels" . | nindent 8 }} - app.kubernetes.io/component: speaker - {{- range $key, $value := .Values.speaker.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} - spec: - {{- if .Values.speaker.runtimeClassName }} - runtimeClassName: {{ .Values.speaker.runtimeClassName }} - {{- end }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ template "metallb.speaker.serviceAccountName" . }} - terminationGracePeriodSeconds: 0 - hostNetwork: true - {{- if .Values.speaker.securityContext }} - securityContext: - {{- toYaml .Values.speaker.securityContext | nindent 8 }} - {{- end }} - volumes: - {{- if .Values.prometheus.speakerMetricsTLSSecret }} - - name: metrics-certs - secret: - secretName: {{ .Values.prometheus.speakerMetricsTLSSecret }} - {{- end }} - {{- if .Values.speaker.memberlist.enabled }} - - name: memberlist - secret: - secretName: {{ include "metallb.secretName" . }} - defaultMode: 420 - {{- end }} - {{- if .Values.speaker.excludeInterfaces.enabled }} - - name: metallb-excludel2 - configMap: - defaultMode: 256 - name: metallb-excludel2 - {{- end }} - {{- if .Values.speaker.frr.enabled }} - - name: frr-sockets - emptyDir: {} - - name: frr-startup - configMap: - name: {{ template "metallb.fullname" . }}-frr-startup - - name: frr-conf - emptyDir: {} - - name: reloader - emptyDir: {} - - name: metrics - emptyDir: {} - initContainers: - # Copies the initial config files with the right permissions to the shared volume. - - name: cp-frr-files - image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }} - securityContext: - runAsUser: 100 - runAsGroup: 101 - command: ["/bin/sh", "-c", "cp -rLf /tmp/frr/* /etc/frr/"] - volumeMounts: - - name: frr-startup - mountPath: /tmp/frr - - name: frr-conf - mountPath: /etc/frr - # Copies the reloader to the shared volume between the speaker and reloader. - - name: cp-reloader - image: {{ .Values.speaker.image.repository }}:{{ .Values.speaker.image.tag | default .Chart.AppVersion }} - command: ["/bin/sh", "-c", "cp -f /frr-reloader.sh /etc/frr_reloader/"] - volumeMounts: - - name: reloader - mountPath: /etc/frr_reloader - # Copies the metrics exporter - - name: cp-metrics - image: {{ .Values.speaker.image.repository }}:{{ .Values.speaker.image.tag | default .Chart.AppVersion }} - command: ["/bin/sh", "-c", "cp -f /frr-metrics /etc/frr_metrics/"] - volumeMounts: - - name: metrics - mountPath: /etc/frr_metrics - shareProcessNamespace: true - {{- end }} - containers: - - name: speaker - image: {{ .Values.speaker.image.repository }}:{{ .Values.speaker.image.tag | default .Chart.AppVersion }} - {{- if .Values.speaker.image.pullPolicy }} - imagePullPolicy: {{ .Values.speaker.image.pullPolicy }} - {{- end }} - {{- if .Values.speaker.command }} - command: - - {{ .Values.speaker.command }} - {{- end }} - args: - - --port={{ .Values.prometheus.metricsPort }} - {{- with .Values.speaker.logLevel }} - - --log-level={{ . }} - {{- end }} - {{- if .Values.loadBalancerClass }} - - --lb-class={{ .Values.loadBalancerClass }} - {{- end }} - {{- if .Values.speaker.wanConfig }} - - --ml-wan-config - {{- end }} - {{- if .Values.speaker.ignoreExcludeLB}} - - --ignore-exclude-lb - {{- end }} - {{- if .Values.prometheus.secureMetricsPort }} - - --host=localhost - {{- end }} - env: - - name: METALLB_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: METALLB_HOST - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.speaker.memberlist.enabled }} - {{- if .Values.speaker.memberlist.mlBindAddrOverride }} - - name: METALLB_ML_BIND_ADDR - value: "{{ .Values.speaker.memberlist.mlBindAddrOverride }}" - {{ else }} - - name: METALLB_ML_BIND_ADDR - valueFrom: - fieldRef: - fieldPath: status.podIP - {{ end }} - - name: METALLB_ML_LABELS - value: "app.kubernetes.io/name={{ include "metallb.name" . }},app.kubernetes.io/component=speaker" - - name: METALLB_ML_BIND_PORT - value: "{{ .Values.speaker.memberlist.mlBindPort }}" - - name: METALLB_ML_SECRET_KEY_PATH - value: "{{ .Values.speaker.memberlist.mlSecretKeyPath }}" - {{- end }} - {{- if .Values.speaker.frr.enabled }} - - name: FRR_CONFIG_FILE - value: /etc/frr_reloader/frr.conf - - name: FRR_RELOADER_PID_FILE - value: /etc/frr_reloader/reloader.pid - - name: METALLB_BGP_TYPE - value: frr - {{- end }} - {{- if .Values.frrk8s.enabled }} - - name: METALLB_BGP_TYPE - value: frr-k8s - {{- end }} - ports: - - name: monitoring - containerPort: {{ .Values.prometheus.metricsPort }} - {{- if .Values.speaker.memberlist.enabled }} - - name: memberlist-tcp - containerPort: {{ .Values.speaker.memberlist.mlBindPort }} - protocol: TCP - - name: memberlist-udp - containerPort: {{ .Values.speaker.memberlist.mlBindPort }} - protocol: UDP - {{- end }} - {{- if .Values.speaker.livenessProbe.enabled }} - livenessProbe: - httpGet: - {{- if .Values.prometheus.secureMetricsPort }} - host: localhost - {{- end }} - path: /metrics - port: monitoring - initialDelaySeconds: {{ .Values.speaker.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.speaker.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.speaker.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.speaker.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.speaker.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.speaker.readinessProbe.enabled }} - readinessProbe: - httpGet: - {{- if .Values.prometheus.secureMetricsPort }} - host: localhost - {{- end }} - path: /metrics - port: monitoring - initialDelaySeconds: {{ .Values.speaker.readinessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.speaker.readinessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.speaker.readinessProbe.timeoutSeconds }} - successThreshold: {{ .Values.speaker.readinessProbe.successThreshold }} - failureThreshold: {{ .Values.speaker.readinessProbe.failureThreshold }} - {{- end }} - {{- with .Values.speaker.resources }} - resources: - {{- toYaml . | nindent 10 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: - - ALL - add: - - NET_RAW - {{- if or .Values.speaker.frr.enabled .Values.speaker.memberlist.enabled .Values.speaker.excludeInterfaces.enabled }} - volumeMounts: - {{- if .Values.speaker.memberlist.enabled }} - - name: memberlist - mountPath: {{ .Values.speaker.memberlist.mlSecretKeyPath }} - {{- end }} - {{- if .Values.speaker.frr.enabled }} - - name: reloader - mountPath: /etc/frr_reloader - {{- end }} - {{- if .Values.speaker.excludeInterfaces.enabled }} - - name: metallb-excludel2 - mountPath: /etc/metallb - {{- end }} - {{- end }} - {{- if .Values.speaker.frr.enabled }} - - name: frr - securityContext: - capabilities: - add: - - NET_ADMIN - - NET_RAW - - SYS_ADMIN - - NET_BIND_SERVICE - image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }} - {{- if .Values.speaker.frr.image.pullPolicy }} - imagePullPolicy: {{ .Values.speaker.frr.image.pullPolicy }} - {{- end }} - env: - - name: TINI_SUBREAPER - value: "true" - volumeMounts: - - name: frr-sockets - mountPath: /var/run/frr - - name: frr-conf - mountPath: /etc/frr - # The command is FRR's default entrypoint & waiting for the log file to appear and tailing it. - # If the log file isn't created in 60 seconds the tail fails and the container is restarted. - # This workaround is needed to have the frr logs as part of kubectl logs -c frr < speaker_pod_name >. - command: - - /bin/sh - - -c - - | - /sbin/tini -- /usr/lib/frr/docker-start & - attempts=0 - until [[ -f /etc/frr/frr.log || $attempts -eq 60 ]]; do - sleep 1 - attempts=$(( $attempts + 1 )) - done - tail -f /etc/frr/frr.log - {{- with .Values.speaker.frr.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- if .Values.speaker.livenessProbe.enabled }} - livenessProbe: - httpGet: - {{- if .Values.prometheus.secureMetricsPort }} - host: localhost - {{- end }} - path: livez - port: {{ .Values.speaker.frr.metricsPort }} - initialDelaySeconds: {{ .Values.speaker.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.speaker.livenessProbe.periodSeconds }} - timeoutSeconds: {{ .Values.speaker.livenessProbe.timeoutSeconds }} - successThreshold: {{ .Values.speaker.livenessProbe.successThreshold }} - failureThreshold: {{ .Values.speaker.livenessProbe.failureThreshold }} - {{- end }} - {{- if .Values.speaker.startupProbe.enabled }} - startupProbe: - httpGet: - {{- if .Values.prometheus.secureMetricsPort }} - host: localhost - {{- end }} - path: /livez - port: {{ .Values.speaker.frr.metricsPort }} - failureThreshold: {{ .Values.speaker.startupProbe.failureThreshold }} - periodSeconds: {{ .Values.speaker.startupProbe.periodSeconds }} - {{- end }} - - name: reloader - image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }} - {{- if .Values.speaker.frr.image.pullPolicy }} - imagePullPolicy: {{ .Values.speaker.frr.image.pullPolicy }} - {{- end }} - command: ["/etc/frr_reloader/frr-reloader.sh"] - volumeMounts: - - name: frr-sockets - mountPath: /var/run/frr - - name: frr-conf - mountPath: /etc/frr - - name: reloader - mountPath: /etc/frr_reloader - {{- with .Values.speaker.reloader.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - - name: frr-metrics - image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }} - command: ["/etc/frr_metrics/frr-metrics"] - args: - - --metrics-port={{ .Values.speaker.frr.metricsPort }} - {{- if .Values.prometheus.secureMetricsPort }} - - --host=localhost - {{- end }} - ports: - - containerPort: {{ .Values.speaker.frr.metricsPort }} - name: monitoring - volumeMounts: - - name: frr-sockets - mountPath: /var/run/frr - - name: frr-conf - mountPath: /etc/frr - - name: metrics - mountPath: /etc/frr_metrics - {{- with .Values.speaker.frrMetrics.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- end }} - {{- if .Values.prometheus.secureMetricsPort }} - - name: kube-rbac-proxy - image: {{ .Values.prometheus.rbacProxy.repository }}:{{ .Values.prometheus.rbacProxy.tag }} - imagePullPolicy: {{ .Values.prometheus.rbacProxy.pullPolicy }} - args: - - --logtostderr - - --secure-listen-address=:{{ .Values.prometheus.secureMetricsPort }} - - --upstream=http://localhost:{{ .Values.prometheus.metricsPort }}/ - - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - {{- if .Values.prometheus.speakerMetricsTLSSecret }} - - --tls-private-key-file=/etc/metrics/tls.key - - --tls-cert-file=/etc/metrics/tls.crt - {{- end }} - ports: - - containerPort: {{ .Values.prometheus.secureMetricsPort }} - name: metricshttps - resources: - requests: - cpu: 10m - memory: 20Mi - terminationMessagePolicy: FallbackToLogsOnError - {{- if .Values.prometheus.speakerMetricsTLSSecret }} - volumeMounts: - - name: metrics-certs - mountPath: /etc/metrics - readOnly: true - {{- end }} - {{ end }} - {{- if .Values.speaker.frr.enabled }} - {{- if .Values.speaker.frr.secureMetricsPort }} - - name: kube-rbac-proxy-frr - image: {{ .Values.prometheus.rbacProxy.repository }}:{{ .Values.prometheus.rbacProxy.tag | default .Chart.AppVersion }} - imagePullPolicy: {{ .Values.prometheus.rbacProxy.pullPolicy }} - args: - - --logtostderr - - --secure-listen-address=:{{ .Values.speaker.frr.secureMetricsPort }} - - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - - --upstream=http://localhost:{{ .Values.speaker.frr.metricsPort }}/ - {{- if .Values.prometheus.speakerMetricsTLSSecret }} - - --tls-private-key-file=/etc/metrics/tls.key - - --tls-cert-file=/etc/metrics/tls.crt - {{- end }} - ports: - - containerPort: {{ .Values.speaker.frr.secureMetricsPort }} - name: frrmetricshttps - env: - - name: METALLB_HOST - valueFrom: - fieldRef: - fieldPath: status.hostIP - resources: - requests: - cpu: 10m - memory: 20Mi - terminationMessagePolicy: FallbackToLogsOnError - {{- if .Values.prometheus.speakerMetricsTLSSecret }} - volumeMounts: - - name: metrics-certs - mountPath: /etc/metrics - readOnly: true - {{- end }} - {{ end }} - {{- end }} - {{- if .Values.speaker.extraContainers }} - {{- toYaml .Values.speaker.extraContainers | nindent 6 }} - {{- end }} - nodeSelector: - "kubernetes.io/os": linux - {{- with .Values.speaker.nodeSelector }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.speaker.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if or .Values.speaker.tolerateMaster .Values.speaker.tolerations }} - tolerations: - {{- if .Values.speaker.tolerateMaster }} - - key: node-role.kubernetes.io/master - effect: NoSchedule - operator: Exists - - key: node-role.kubernetes.io/control-plane - effect: NoSchedule - operator: Exists - {{- end }} - {{- with .Values.speaker.tolerations }} - {{- toYaml . | nindent 6 }} - {{- end }} - {{- end }} - {{- with .Values.speaker.priorityClassName }} - priorityClassName: {{ . | quote }} - {{- end }} -{{- end }} diff --git a/charts/metallb/metallb/templates/webhooks.yaml b/charts/metallb/metallb/templates/webhooks.yaml deleted file mode 100644 index e708beea6..000000000 --- a/charts/metallb/metallb/templates/webhooks.yaml +++ /dev/null @@ -1,150 +0,0 @@ -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: metallb-webhook-configuration - labels: - {{- include "metallb.labels" . | nindent 4 }} -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: metallb-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-metallb-io-v1beta2-bgppeer - failurePolicy: {{ .Values.crds.validationFailurePolicy }} - name: bgppeervalidationwebhook.metallb.io - rules: - - apiGroups: - - metallb.io - apiVersions: - - v1beta2 - operations: - - CREATE - - UPDATE - resources: - - bgppeers - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: metallb-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-metallb-io-v1beta1-ipaddresspool - failurePolicy: {{ .Values.crds.validationFailurePolicy }} - name: ipaddresspoolvalidationwebhook.metallb.io - rules: - - apiGroups: - - metallb.io - apiVersions: - - v1beta1 - operations: - - CREATE - - UPDATE - resources: - - ipaddresspools - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: metallb-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-metallb-io-v1beta1-bgpadvertisement - failurePolicy: {{ .Values.crds.validationFailurePolicy }} - name: bgpadvertisementvalidationwebhook.metallb.io - rules: - - apiGroups: - - metallb.io - apiVersions: - - v1beta1 - operations: - - CREATE - - UPDATE - resources: - - bgpadvertisements - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: metallb-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-metallb-io-v1beta1-community - failurePolicy: {{ .Values.crds.validationFailurePolicy }} - name: communityvalidationwebhook.metallb.io - rules: - - apiGroups: - - metallb.io - apiVersions: - - v1beta1 - operations: - - CREATE - - UPDATE - resources: - - communities - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: metallb-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-metallb-io-v1beta1-bfdprofile - failurePolicy: {{ .Values.crds.validationFailurePolicy }} - name: bfdprofilevalidationwebhook.metallb.io - rules: - - apiGroups: - - metallb.io - apiVersions: - - v1beta1 - operations: - - CREATE - - DELETE - resources: - - bfdprofiles - sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: metallb-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-metallb-io-v1beta1-l2advertisement - failurePolicy: {{ .Values.crds.validationFailurePolicy }} - name: l2advertisementvalidationwebhook.metallb.io - rules: - - apiGroups: - - metallb.io - apiVersions: - - v1beta1 - operations: - - CREATE - - UPDATE - resources: - - l2advertisements - sideEffects: None ---- -apiVersion: v1 -kind: Service -metadata: - name: metallb-webhook-service - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} -spec: - ports: - - port: 443 - targetPort: 9443 - selector: - {{- include "metallb.selectorLabels" . | nindent 4 }} - app.kubernetes.io/component: controller ---- -apiVersion: v1 -kind: Secret -metadata: - name: metallb-webhook-cert - namespace: {{ .Release.Namespace | quote }} - labels: - {{- include "metallb.labels" . | nindent 4 }} diff --git a/charts/metallb/metallb/values.schema.json b/charts/metallb/metallb/values.schema.json deleted file mode 100644 index bc0dd8402..000000000 --- a/charts/metallb/metallb/values.schema.json +++ /dev/null @@ -1,448 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft-07/schema#", - "title": "Values", - "type": "object", - "definitions": { - "prometheusAlert": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "labels": { - "type": "object", - "additionalProperties": { "type": "string" } - } - }, - "required": [ "enabled" ] - }, - "probe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - }, - "required": [ - "failureThreshold", - "initialDelaySeconds", - "periodSeconds", - "successThreshold", - "timeoutSeconds" - ] - }, - "component": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "logLevel": { - "type": "string", - "enum": [ "all", "debug", "info", "warn", "error", "none" ] - }, - "image": { - "type": "object", - "properties": { - "repository": { - "type": "string" - }, - "tag": { - "anyOf": [ - { "type": "string" }, - { "type": "null" } - ] - }, - "pullPolicy": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "string", - "enum": [ "Always", "IfNotPresent", "Never" ] - } - ] - } - } - }, - "serviceAccount": { - "type": "object", - "properties": { - "create": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "annotations": { - "type": "object" - } - } - }, - "resources": { - "type": "object" - }, - "nodeSelector": { - "type": "object" - }, - "tolerations": { - "type": "array", - "items": { - "type": "object" - } - }, - "priorityClassName": { - "type":"string" - }, - "runtimeClassName": { - "type":"string" - }, - "affinity": { - "type": "object" - }, - "podAnnotations": { - "type": "object" - }, - "livenessProbe": { - "$ref": "#/definitions/probe" - }, - "readinessProbe": { - "$ref": "#/definitions/probe" - } - }, - "required": [ - "image", - "serviceAccount" - ] - } - }, - "properties": { - "imagePullSecrets": { - "description": "Secrets used for pulling images", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - }, - "required": [ "name" ], - "additionalProperties": false - } - }, - "nameOverride": { - "description": "Override chart name", - "type": "string" - }, - "fullNameOverride": { - "description": "Override fully qualified app name", - "type": "string" - }, - "configInLine": { - "description": "MetalLB configuration", - "type": "object" - }, - "loadBalancerClass": { - "type":"string" - }, - "rbac": { - "description": "RBAC configuration", - "type": "object", - "properties": { - "create": { - "description": "Enable RBAC", - "type": "boolean" - } - } - }, - "prometheus": { - "description": "Prometheus monitoring config", - "type": "object", - "properties": { - "scrapeAnnotations": { "type": "boolean" }, - "metricsPort": { "type": "integer" }, - "secureMetricsPort": { "type": "integer" }, - "rbacPrometheus": { "type": "boolean" }, - "serviceAccount": { "type": "string" }, - "namespace": { "type": "string" }, - "rbacProxy": { - "description": "kube-rbac-proxy configuration", - "type": "object", - "properties": { - "repository": { "type": "string" }, - "tag": { "type": "string" } - } - }, - "podMonitor": { - "description": "Prometheus Operator PodMonitors", - "type": "object", - "properties": { - "enabled": { "type": "boolean" }, - "additionalMonitors": { "type": "object" }, - "jobLabel": { "type": "string" }, - "interval": { - "anyOf": [ - { "type": "integer" }, - { "type": "null" } - ] - }, - "metricRelabelings": { - "type": "array", - "items": { - "type": "object" - } - }, - "relabelings": { - "type": "array", - "items": { - "type": "object" - } - } - } - }, - "serviceMonitor": { - "description": "Prometheus Operator ServiceMonitors", - "type": "object", - "properties": { - "enabled": { "type": "boolean" }, - "jobLabel": { "type": "string" }, - "interval": { - "anyOf": [ - { "type": "integer" }, - { "type": "null" } - ] - }, - "metricRelabelings": { - "type": "array", - "items": { - "type": "object" - } - }, - "relabelings": { - "type": "array", - "items": { - "type": "object" - } - } - } - }, - "prometheusRule": { - "description": "Prometheus Operator alertmanager alerts", - "type": "object", - "properties": { - "enabled": { "type": "boolean" }, - "additionalMonitors": { "type": "object" }, - "staleConfig": { "$ref": "#/definitions/prometheusAlert" }, - "configNotLoaded": { "$ref": "#/definitions/prometheusAlert" }, - "addressPoolExhausted": { "$ref": "#/definitions/prometheusAlert" }, - "addressPoolUsage": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "thresholds": { - "type": "array", - "items": { - "type": "object", - "properties": { - "percent": { - "type": "integer", - "minimum": 0, - "maximum": 100 - }, - "labels": { - "type": "object", - "additionalProperties": { "type": "string" } - } - }, - "required": [ "percent" ] - } - } - }, - "required": [ "enabled" ] - }, - "bgpSessionDown": { "$ref": "#/definitions/prometheusAlert" }, - "extraAlerts": { - "type": "array", - "items": { - "type": "object" - } - } - }, - "required": [ - "enabled", - "staleConfig", - "configNotLoaded", - "addressPoolExhausted", - "addressPoolUsage", - "bgpSessionDown" - ] - } - }, - "required": [ "podMonitor", "prometheusRule" ] - }, - "controller": { - "allOf": [ - { "$ref": "#/definitions/component" }, - { "description": "MetalLB Controller", - "type": "object", - "properties": { - "strategy": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - }, - "required": [ "type" ] - }, - "command" : { - "type": "string" - }, - "webhookMode" : { - "type": "string" - }, - "extraContainers": { - "type": "array", - "items": { - "type": "object" - } - } - } - } - ] - }, - "speaker": { - "allOf": [ - { "$ref": "#/definitions/component" }, - { "description": "MetalLB Speaker", - "type": "object", - "properties": { - "tolerateMaster": { - "type": "boolean" - }, - "memberlist": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "mlBindPort": { - "type": "integer" - }, - "mlBindAddrOverride": { - "type": "string" - }, - "mlSecretKeyPath": { - "type": "string" - } - } - }, - "excludeInterfaces": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - } - } - }, - "ignoreExcludeLB": { - "type": "boolean" - }, - "updateStrategy": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - }, - "required": [ "type" ] - }, - "runtimeClassName": { - "type": "string" - }, - "securityContext": { - "type": "object" - }, - "secretName": { - "type": "string" - }, - "frr": { - "description": "Install FRR container in speaker deployment", - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "image": { "$ref": "#/definitions/component/properties/image" }, - "metricsPort": { "type": "integer" }, - "secureMetricsPort": { "type": "integer" }, - "resources:": { "type": "object" } - }, - "required": [ "enabled" ] - }, - "command" : { - "type": "string" - }, - "reloader": { - "type": "object", - "properties": { - "resources": { "type": "object" } - } - }, - "frrMetrics": { - "type": "object", - "properties": { - "resources": { "type": "object" } - } - }, - "extraContainers": { - "type": "array", - "items": { - "type": "object" - } - } - }, - "required": [ "tolerateMaster" ] - } - ] - }, - "crds": { - "description": "CRD configuration", - "type": "object", - "properties": { - "enabled": { - "description": "Enable CRDs", - "type": "boolean" - }, - "validationFailurePolicy": { - "description": "Failure policy to use with validating webhooks", - "type": "string", - "enum": [ "Ignore", "Fail" ] - } - } - } - }, - "required": [ - "controller", - "speaker" - ] -} diff --git a/charts/metallb/metallb/values.yaml b/charts/metallb/metallb/values.yaml deleted file mode 100644 index 738f25f8a..000000000 --- a/charts/metallb/metallb/values.yaml +++ /dev/null @@ -1,363 +0,0 @@ -# Default values for metallb. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -imagePullSecrets: [] -nameOverride: "" -fullnameOverride: "" -loadBalancerClass: "" - -# To configure MetalLB, you must specify ONE of the following two -# options. - -rbac: - # create specifies whether to install and use RBAC rules. - create: true - -prometheus: - # scrape annotations specifies whether to add Prometheus metric - # auto-collection annotations to pods. See - # https://github.com/prometheus/prometheus/blob/release-2.1/documentation/examples/prometheus-kubernetes.yml - # for a corresponding Prometheus configuration. Alternatively, you - # may want to use the Prometheus Operator - # (https://github.com/coreos/prometheus-operator) for more powerful - # monitoring configuration. If you use the Prometheus operator, this - # can be left at false. - scrapeAnnotations: false - - # port both controller and speaker will listen on for metrics - metricsPort: 7472 - - # if set, enables rbac proxy on the controller and speaker to expose - # the metrics via tls. - # secureMetricsPort: 9120 - - # the name of the secret to be mounted in the speaker pod - # to expose the metrics securely. If not present, a self signed - # certificate to be used. - speakerMetricsTLSSecret: "" - - # the name of the secret to be mounted in the controller pod - # to expose the metrics securely. If not present, a self signed - # certificate to be used. - controllerMetricsTLSSecret: "" - - # prometheus doens't have the permission to scrape all namespaces so we give it permission to scrape metallb's one - rbacPrometheus: true - - # the service account used by prometheus - # required when " .Values.prometheus.rbacPrometheus == true " and " .Values.prometheus.podMonitor.enabled=true or prometheus.serviceMonitor.enabled=true " - serviceAccount: "" - - # the namespace where prometheus is deployed - # required when " .Values.prometheus.rbacPrometheus == true " and " .Values.prometheus.podMonitor.enabled=true or prometheus.serviceMonitor.enabled=true " - namespace: "" - - # the image to be used for the kuberbacproxy container - rbacProxy: - repository: gcr.io/kubebuilder/kube-rbac-proxy - tag: v0.12.0 - pullPolicy: - - # Prometheus Operator PodMonitors - podMonitor: - # enable support for Prometheus Operator - enabled: false - - # optional additionnal labels for podMonitors - additionalLabels: {} - - # optional annotations for podMonitors - annotations: {} - - # Job label for scrape target - jobLabel: "app.kubernetes.io/name" - - # Scrape interval. If not set, the Prometheus default scrape interval is used. - interval: - - # metric relabel configs to apply to samples before ingestion. - metricRelabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - # relabel configs to apply to samples before ingestion. - relabelings: [] - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # target_label: nodename - # replacement: $1 - # action: replace - - # Prometheus Operator ServiceMonitors. To be used as an alternative - # to podMonitor, supports secure metrics. - serviceMonitor: - # enable support for Prometheus Operator - enabled: false - - speaker: - # optional additional labels for the speaker serviceMonitor - additionalLabels: {} - # optional additional annotations for the speaker serviceMonitor - annotations: {} - # optional tls configuration for the speaker serviceMonitor, in case - # secure metrics are enabled. - tlsConfig: - insecureSkipVerify: true - - controller: - # optional additional labels for the controller serviceMonitor - additionalLabels: {} - # optional additional annotations for the controller serviceMonitor - annotations: {} - # optional tls configuration for the controller serviceMonitor, in case - # secure metrics are enabled. - tlsConfig: - insecureSkipVerify: true - - # Job label for scrape target - jobLabel: "app.kubernetes.io/name" - - # Scrape interval. If not set, the Prometheus default scrape interval is used. - interval: - - # metric relabel configs to apply to samples before ingestion. - metricRelabelings: [] - # - action: keep - # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' - # sourceLabels: [__name__] - - # relabel configs to apply to samples before ingestion. - relabelings: [] - # - sourceLabels: [__meta_kubernetes_pod_node_name] - # separator: ; - # regex: ^(.*)$ - # target_label: nodename - # replacement: $1 - # action: replace - - # Prometheus Operator alertmanager alerts - prometheusRule: - # enable alertmanager alerts - enabled: false - - # optional additionnal labels for prometheusRules - additionalLabels: {} - - # optional annotations for prometheusRules - annotations: {} - - # MetalLBStaleConfig - staleConfig: - enabled: true - labels: - severity: warning - - # MetalLBConfigNotLoaded - configNotLoaded: - enabled: true - labels: - severity: warning - - # MetalLBAddressPoolExhausted - addressPoolExhausted: - enabled: true - labels: - severity: alert - - addressPoolUsage: - enabled: true - thresholds: - - percent: 75 - labels: - severity: warning - - percent: 85 - labels: - severity: warning - - percent: 95 - labels: - severity: alert - - # MetalLBBGPSessionDown - bgpSessionDown: - enabled: true - labels: - severity: alert - - extraAlerts: [] - -# controller contains configuration specific to the MetalLB cluster -# controller. -controller: - enabled: true - # -- Controller log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none` - logLevel: info - # command: /controller - # webhookMode: enabled - image: - repository: quay.io/metallb/controller - tag: - pullPolicy: - ## @param controller.updateStrategy.type Metallb controller deployment strategy type. - ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy - ## e.g: - ## strategy: - ## type: RollingUpdate - ## rollingUpdate: - ## maxSurge: 25% - ## maxUnavailable: 25% - ## - strategy: - type: RollingUpdate - serviceAccount: - # Specifies whether a ServiceAccount should be created - create: true - # The name of the ServiceAccount to use. If not set and create is - # true, a name is generated using the fullname template - name: "" - annotations: {} - securityContext: - runAsNonRoot: true - # nobody - runAsUser: 65534 - fsGroup: 65534 - resources: {} - # limits: - # cpu: 100m - # memory: 100Mi - nodeSelector: {} - tolerations: [] - priorityClassName: "" - runtimeClassName: "" - affinity: {} - podAnnotations: {} - labels: {} - livenessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - tlsMinVersion: "VersionTLS12" - tlsCipherSuites: "" - - extraContainers: [] - -# speaker contains configuration specific to the MetalLB speaker -# daemonset. -speaker: - enabled: true - # command: /speaker - # -- Speaker log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none` - logLevel: info - tolerateMaster: true - memberlist: - enabled: true - mlBindPort: 7946 - mlBindAddrOverride: "" - mlSecretKeyPath: "/etc/ml_secret_key" - excludeInterfaces: - enabled: true - # ignore the exclude-from-external-loadbalancer label - ignoreExcludeLB: false - - image: - repository: quay.io/metallb/speaker - tag: - pullPolicy: - ## @param speaker.updateStrategy.type Speaker daemonset strategy type - ## ref: https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/ - ## - updateStrategy: - ## StrategyType - ## Can be set to RollingUpdate or OnDelete - ## - type: RollingUpdate - serviceAccount: - # Specifies whether a ServiceAccount should be created - create: true - # The name of the ServiceAccount to use. If not set and create is - # true, a name is generated using the fullname template - name: "" - annotations: {} - securityContext: {} - ## Defines a secret name for the controller to generate a memberlist encryption secret - ## By default secretName: {{ "metallb.fullname" }}-memberlist - ## - # secretName: - resources: {} - # limits: - # cpu: 100m - # memory: 100Mi - nodeSelector: {} - tolerations: [] - priorityClassName: "" - affinity: {} - ## Selects which runtime class will be used by the pod. - runtimeClassName: "" - podAnnotations: {} - labels: {} - livenessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - enabled: true - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - startupProbe: - enabled: true - failureThreshold: 30 - periodSeconds: 5 - # frr contains configuration specific to the MetalLB FRR container, - # for speaker running alongside FRR. - frr: - enabled: true - image: - repository: quay.io/frrouting/frr - tag: 9.0.2 - pullPolicy: - metricsPort: 7473 - resources: {} - - # if set, enables a rbac proxy sidecar container on the speaker to - # expose the frr metrics via tls. - # secureMetricsPort: 9121 - - - reloader: - resources: {} - - frrMetrics: - resources: {} - - extraContainers: [] - -crds: - enabled: true - validationFailurePolicy: Fail - -# frrk8s contains the configuration related to using an frrk8s instance -# (github.com/metallb/frr-k8s) as the backend for the BGP implementation. -# This allows configuring additional frr parameters in combination to those -# applied by MetalLB. -frrk8s: - # if set, enables frrk8s as a backend. This is mutually exclusive to frr - # mode. - enabled: false diff --git a/index.yaml b/index.yaml index 30ca7083e..3bd8e622e 100644 --- a/index.yaml +++ b/index.yaml @@ -20061,154 +20061,6 @@ entries: urls: - assets/loft/loft-3.2.0.tgz version: 3.2.0 - metallb: - - annotations: - catalog.cattle.io/certified: partner - catalog.cattle.io/display-name: MetalLB - catalog.cattle.io/kube-version: '>= 1.19.0-0' - catalog.cattle.io/namespace: metallb-system - catalog.cattle.io/release-name: metallb - apiVersion: v2 - appVersion: v0.14.5 - created: "2024-04-20T00:52:22.273537026Z" - dependencies: - - condition: crds.enabled - name: crds - repository: file://./charts/crds - version: 0.14.5 - - condition: frrk8s.enabled - name: frr-k8s - repository: file://./charts/frr-k8s - version: 0.0.11 - description: A network load-balancer implementation for Kubernetes using standard - routing protocols - digest: 83cb85da29b1007a4002280f5c8c93f50420793e550012270fe10e2e3790335a - home: https://metallb.universe.tf - icon: file://assets/icons/metallb.png - kubeVersion: '>= 1.19.0-0' - name: metallb - sources: - - https://github.com/metallb/metallb - type: application - urls: - - assets/metallb/metallb-0.14.5.tgz - version: 0.14.5 - - annotations: - catalog.cattle.io/certified: partner - catalog.cattle.io/display-name: MetalLB - catalog.cattle.io/kube-version: '>= 1.19.0-0' - catalog.cattle.io/namespace: metallb-system - catalog.cattle.io/release-name: metallb - apiVersion: v2 - appVersion: v0.14.4 - created: "2024-04-03T10:30:29.963141386-06:00" - dependencies: - - condition: crds.enabled - name: crds - repository: file://./charts/crds - version: 0.14.4 - - condition: frrk8s.enabled - name: frr-k8s - repository: file://./charts/frr-k8s - version: 0.0.10 - description: A network load-balancer implementation for Kubernetes using standard - routing protocols - digest: 43b4e3fac14281b840f7b4fa1cdd90957a56eb9f28ce9522e1c753ad98ea5b65 - home: https://metallb.universe.tf - icon: file://assets/icons/metallb.png - kubeVersion: '>= 1.19.0-0' - name: metallb - sources: - - https://github.com/metallb/metallb - type: application - urls: - - assets/metallb/metallb-0.14.4.tgz - version: 0.14.4 - - annotations: - catalog.cattle.io/certified: partner - catalog.cattle.io/display-name: MetalLB - catalog.cattle.io/kube-version: '>= 1.19.0-0' - catalog.cattle.io/namespace: metallb-system - catalog.cattle.io/release-name: metallb - apiVersion: v2 - appVersion: v0.14.3 - created: "2024-02-09T14:31:36.279713775Z" - dependencies: - - condition: crds.enabled - name: crds - repository: file://./charts/crds - version: 0.14.3 - - condition: frrk8s.enabled - name: frr-k8s - repository: file://./charts/frr-k8s - version: 0.0.8 - description: A network load-balancer implementation for Kubernetes using standard - routing protocols - digest: 201260d67c0960dddaa35572e5fbb2a774354013596ecf6f525016d216d9e487 - home: https://metallb.universe.tf - icon: file://assets/icons/metallb.png - kubeVersion: '>= 1.19.0-0' - name: metallb - sources: - - https://github.com/metallb/metallb - type: application - urls: - - assets/metallb/metallb-0.14.3.tgz - version: 0.14.3 - - annotations: - catalog.cattle.io/certified: partner - catalog.cattle.io/display-name: MetalLB - catalog.cattle.io/kube-version: '>= 1.19.0-0' - catalog.cattle.io/namespace: metallb-system - catalog.cattle.io/release-name: metallb - apiVersion: v2 - appVersion: v0.13.12 - created: "2023-10-20T22:25:48.867455386Z" - dependencies: - - condition: crds.enabled - name: crds - repository: file://./charts/crds - version: 0.13.12 - description: A network load-balancer implementation for Kubernetes using standard - routing protocols - digest: dbea71b0de1ae5e5f18ad5536a33245d115a53bda2d3402a76e5a652c54cd8a1 - home: https://metallb.universe.tf - icon: file://assets/icons/metallb.png - kubeVersion: '>= 1.19.0-0' - name: metallb - sources: - - https://github.com/metallb/metallb - type: application - urls: - - assets/metallb/metallb-0.13.12.tgz - version: 0.13.12 - - annotations: - catalog.cattle.io/certified: partner - catalog.cattle.io/display-name: MetalLB - catalog.cattle.io/kube-version: '>= 1.19.0-0' - catalog.cattle.io/namespace: metallb-system - catalog.cattle.io/release-name: metallb - apiVersion: v2 - appVersion: v0.13.11 - created: "2023-09-05T12:50:43.404217854Z" - dependencies: - - condition: crds.enabled - name: crds - repository: file://./charts/crds - version: 0.13.11 - description: A network load-balancer implementation for Kubernetes using standard - routing protocols - digest: 142c1d911670b47058094d22ee9288590f3daacdda9ceca3b8dff40bf7cd6848 - home: https://metallb.universe.tf - icon: file://assets/icons/metallb.png - kubeVersion: '>= 1.19.0-0' - name: metallb - sources: - - https://github.com/metallb/metallb - type: application - urls: - - assets/metallb/metallb-0.13.11.tgz - version: 0.13.11 minio-operator: - annotations: catalog.cattle.io/certified: partner diff --git a/packages/metallb/metallb/upstream.yaml b/packages/metallb/metallb/upstream.yaml deleted file mode 100644 index 94493b39b..000000000 --- a/packages/metallb/metallb/upstream.yaml +++ /dev/null @@ -1,7 +0,0 @@ -HelmRepo: https://metallb.github.io/metallb -HelmChart: metallb -Vendor: MetalLB -DisplayName: MetalLB -Namespace: metallb-system -ChartMetadata: - icon: https://metallb.universe.tf/images/logo/metallb-blue.png