From 1c0fcf83a9c0d8a0b287177c5bebe02360b155de Mon Sep 17 00:00:00 2001 From: Juan Ignacio Donoso Date: Thu, 19 Dec 2024 19:15:27 -0300 Subject: [PATCH] feat(emqx): update database and init user scripts --- .../database/emqx/app/externalsecret.yaml | 25 +++- .../apps/database/emqx/app/helmrelease.yaml | 1 + .../apps/database/emqx/cluster/cluster.yaml | 37 ++---- .../database/emqx/cluster/kustomization.yaml | 6 - .../emqx/cluster/resources/init-mqtt.py | 78 ------------ .../emqx/exporter/externalsecret.yaml | 25 ---- .../database/emqx/exporter/helmrelease.yaml | 111 ------------------ .../database/emqx/exporter/kustomization.yaml | 7 -- kubernetes/apps/database/emqx/ks.yaml | 24 ---- 9 files changed, 34 insertions(+), 280 deletions(-) delete mode 100644 kubernetes/apps/database/emqx/cluster/resources/init-mqtt.py delete mode 100644 kubernetes/apps/database/emqx/exporter/externalsecret.yaml delete mode 100644 kubernetes/apps/database/emqx/exporter/helmrelease.yaml delete mode 100644 kubernetes/apps/database/emqx/exporter/kustomization.yaml diff --git a/kubernetes/apps/database/emqx/app/externalsecret.yaml b/kubernetes/apps/database/emqx/app/externalsecret.yaml index eaa44f810..337d121a9 100644 --- a/kubernetes/apps/database/emqx/app/externalsecret.yaml +++ b/kubernetes/apps/database/emqx/app/externalsecret.yaml @@ -15,10 +15,27 @@ spec: data: EMQX_DASHBOARD__DEFAULT_USERNAME: "{{ .EMQX_DASHBOARD__DEFAULT_USERNAME }}" EMQX_DASHBOARD__DEFAULT_PASSWORD: "{{ .EMQX_DASHBOARD__DEFAULT_PASSWORD }}" - X_EMQX_MQTT_USERNAME: "{{ .X_EMQX_MQTT_USERNAME }}" - X_EMQX_MQTT_PASSWORD: "{{ .X_EMQX_MQTT_PASSWORD }}" - X_EMQX_APIKEY_KEY: "{{ .X_EMQX_APIKEY_KEY }}" - X_EMQX_APIKEY_SECRET: "{{ .X_EMQX_APIKEY_SECRET }}" + dataFrom: + - extract: + key: emqx +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1beta1.json +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: emqx-init-user +spec: + refreshInterval: 5m + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-connect + target: + name: emqx-init-user-secret + template: + engineVersion: v2 + data: + init-user.json: | + [{"user_id": "{{ .X_EMQX_MQTT_USERNAME }}", "password": "{{ .X_EMQX_MQTT_PASSWORD }}", "is_superuser": true}] dataFrom: - extract: key: emqx diff --git a/kubernetes/apps/database/emqx/app/helmrelease.yaml b/kubernetes/apps/database/emqx/app/helmrelease.yaml index f99a3b1df..0fc04da90 100644 --- a/kubernetes/apps/database/emqx/app/helmrelease.yaml +++ b/kubernetes/apps/database/emqx/app/helmrelease.yaml @@ -27,5 +27,6 @@ spec: namespace: cert-manager values: fullnameOverride: emqx-operator + replicaCount: 2 image: repository: ghcr.io/emqx/emqx-operator diff --git a/kubernetes/apps/database/emqx/cluster/cluster.yaml b/kubernetes/apps/database/emqx/cluster/cluster.yaml index aba6d3a8d..dba3dc35a 100644 --- a/kubernetes/apps/database/emqx/cluster/cluster.yaml +++ b/kubernetes/apps/database/emqx/cluster/cluster.yaml @@ -12,9 +12,11 @@ spec: backend = "built_in_database" mechanism = "password_based" password_hash_algorithm { - name = "bcrypt", + name = "bcrypt" } user_id_type = "username" + bootstrap_file = "/opt/init-user.json" + bootstrap_type = "plain" } authorization { sources = [ @@ -25,39 +27,24 @@ spec: ] no_match: "deny" } - bootstrapAPIKeys: - - secretRef: - key: - secretName: emqx-secret - secretKey: X_EMQX_APIKEY_KEY - secret: - secretName: emqx-secret - secretKey: X_EMQX_APIKEY_SECRET coreTemplate: metadata: annotations: reloader.stakater.com/auto: "true" spec: replicas: 3 - envFrom: &envFrom + envFrom: - secretRef: name: emqx-secret - extraContainers: - - name: init-mqtt - image: docker.io/library/python:3.13-alpine - env: - - name: X_EMQX_ADDRESS - value: emqx-dashboard.database.svc.cluster.local:18083 - envFrom: *envFrom - command: ["python", "/init-mqtt.py"] - volumeMounts: - - name: init-mqtt - mountPath: /init-mqtt.py - subPath: init-mqtt.py + extraVolumeMounts: + - name: init-user + mountPath: /opt/init-user.json + subPath: init-user.json + readOnly: true extraVolumes: - - name: init-mqtt - configMap: - name: emqx-init-mqtt-configmap + - name: init-user + secret: + secretName: emqx-init-user-secret listenersServiceTemplate: metadata: annotations: diff --git a/kubernetes/apps/database/emqx/cluster/kustomization.yaml b/kubernetes/apps/database/emqx/cluster/kustomization.yaml index d4de36fd1..83d325ddb 100644 --- a/kubernetes/apps/database/emqx/cluster/kustomization.yaml +++ b/kubernetes/apps/database/emqx/cluster/kustomization.yaml @@ -6,9 +6,3 @@ resources: - ./cluster.yaml - ./ingress.yaml - ./podmonitor.yaml -configMapGenerator: - - name: emqx-init-mqtt-configmap - files: - - init-mqtt.py=./resources/init-mqtt.py -generatorOptions: - disableNameSuffixHash: true diff --git a/kubernetes/apps/database/emqx/cluster/resources/init-mqtt.py b/kubernetes/apps/database/emqx/cluster/resources/init-mqtt.py deleted file mode 100644 index 6cadd72ae..000000000 --- a/kubernetes/apps/database/emqx/cluster/resources/init-mqtt.py +++ /dev/null @@ -1,78 +0,0 @@ -import os -import json -import time -from typing import Optional -from urllib.request import Request, urlopen -from urllib.error import URLError - -class EMQXManager: - def __init__(self, emqx_address: str, admin_username: str, admin_password: str, - mqtt_username: str, mqtt_password: str) -> None: - self.emqx_address = emqx_address - self.admin_username = admin_username - self.admin_password = admin_password - self.mqtt_username = mqtt_username - self.mqtt_password = mqtt_password - - def wait_for_emqx(self) -> None: - while True: - try: - response = urlopen(f"http://{self.emqx_address}/api/v5/status") - if response.getcode() == 200: - print("EMQX started, ready to initialize..") - break - except URLError: - print("Waiting for EMQX to start..") - time.sleep(5) - - def get_api_token(self) -> Optional[str]: - data = json.dumps({"username": self.admin_username, "password": self.admin_password}).encode('utf-8') - req = Request(f"http://{self.emqx_address}/api/v5/login", data=data, headers={'Content-Type': 'application/json'}) - try: - with urlopen(req) as response: - response_data = json.loads(response.read().decode('utf-8')) - return response_data.get('token', None) - except URLError as e: - print(f"Error: {e}") - return None - - def create_mqtt_user(self, api_token: str) -> bool: - data = json.dumps({"user_id": self.mqtt_username, "password": self.mqtt_password, "is_superuser": True}).encode('utf-8') - headers = {'Authorization': f'Bearer {api_token}', 'Content-Type': 'application/json'} - req = Request(f"http://{self.emqx_address}/api/v5/authentication/password_based:built_in_database/users", data=data, headers=headers) - try: - with urlopen(req) as response: - return response.getcode() == 200 - except URLError as e: - print(f"Error: {e}") - return False - -def main() -> None: - emqx_address = os.environ.get('X_EMQX_ADDRESS') - admin_username = os.environ.get('EMQX_DASHBOARD__DEFAULT_USERNAME') - admin_password = os.environ.get('EMQX_DASHBOARD__DEFAULT_PASSWORD') - mqtt_username = os.environ.get('X_EMQX_MQTT_USERNAME') - mqtt_password = os.environ.get('X_EMQX_MQTT_PASSWORD') - - if not all([emqx_address, admin_username, admin_password, mqtt_username, mqtt_password]): - print("Missing environment variables.") - return - - emqx_manager = EMQXManager(emqx_address, admin_username, admin_password, mqtt_username, mqtt_password) - emqx_manager.wait_for_emqx() - - api_token = emqx_manager.get_api_token() - if api_token: - success = emqx_manager.create_mqtt_user(api_token) - if success: - print(f"User {mqtt_username} created successfully.") - else: - print(f"Error creating user {mqtt_username} or user already exists.") - else: - print("Login failed.") - - while True: - time.sleep(1) - -if __name__ == "__main__": - main() diff --git a/kubernetes/apps/database/emqx/exporter/externalsecret.yaml b/kubernetes/apps/database/emqx/exporter/externalsecret.yaml deleted file mode 100644 index d6f4dab1c..000000000 --- a/kubernetes/apps/database/emqx/exporter/externalsecret.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- -# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1beta1.json -apiVersion: external-secrets.io/v1beta1 -kind: ExternalSecret -metadata: - name: emqx-exporter -spec: - secretStoreRef: - kind: ClusterSecretStore - name: onepassword-connect - target: - name: emqx-exporter-secret - template: - engineVersion: v2 - data: - config.yaml: | - metrics: - target: emqx-dashboard.database.svc.cluster.local:18083 - api_key: "{{ .X_EMQX_APIKEY_KEY }}" - api_secret: "{{ .X_EMQX_APIKEY_SECRET }}" - probes: - - target: emqx-listeners.database.svc.cluster.local:1883 - dataFrom: - - extract: - key: emqx diff --git a/kubernetes/apps/database/emqx/exporter/helmrelease.yaml b/kubernetes/apps/database/emqx/exporter/helmrelease.yaml deleted file mode 100644 index 759c377c9..000000000 --- a/kubernetes/apps/database/emqx/exporter/helmrelease.yaml +++ /dev/null @@ -1,111 +0,0 @@ ---- -# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: emqx-exporter -spec: - interval: 30m - chart: - spec: - chart: app-template - version: 3.5.1 - sourceRef: - kind: HelmRepository - name: bjw-s - namespace: flux-system - install: - remediation: - retries: 3 - upgrade: - cleanupOnFail: true - remediation: - strategy: rollback - retries: 3 - values: - controllers: - emqx-exporter: - strategy: RollingUpdate - annotations: - reloader.stakater.com/auto: "true" - containers: - app: - image: - repository: ghcr.io/emqx/emqx-exporter - tag: 0.2.9@sha256:54c1e9563e4065482c9d1149cb5faac196dd6d1892de2b4888e0e3dc75a8da91 - args: ["--config.file", "/etc/emqx-exporter/config.yaml"] - probes: - liveness: &probes - enabled: true - custom: true - spec: - httpGet: - path: / - port: &port 8085 - initialDelaySeconds: 0 - periodSeconds: 10 - timeoutSeconds: 1 - failureThreshold: 3 - readiness: *probes - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: { drop: ["ALL"] } - resources: - requests: - cpu: 10m - limits: - memory: 128Mi - defaultPodOptions: - securityContext: - runAsNonRoot: true - runAsUser: 65534 - runAsGroup: 65534 - seccompProfile: { type: RuntimeDefault } - service: - app: - controller: emqx-exporter - ports: - http: - port: *port - serviceMonitor: - app: - serviceName: emqx-exporter - endpoints: - - port: http - scheme: http - path: /metrics - interval: 1m - scrapeTimeout: 10s - relabelings: &relabelings - - action: replace - # user-defined cluster name, requires unique - replacement: emqx - targetLabel: cluster - - action: replace - # fix value, don't modify - replacement: exporter - targetLabel: from - - action: replace - # fix value, don't modify - sourceLabels: ['pod'] - regex: '(.*)-.*-.*' - replacement: $1 - targetLabel: "instance" - - action: labeldrop - # fix value, don't modify - regex: 'pod' - - port: http - scheme: http - path: /probe - interval: 1m - scrapeTimeout: 10s - relabelings: *relabelings - persistence: - config: - type: secret - name: emqx-exporter-secret - globalMounts: - - path: /etc/emqx-exporter/config.yaml - subPath: config.yaml - readOnly: true diff --git a/kubernetes/apps/database/emqx/exporter/kustomization.yaml b/kubernetes/apps/database/emqx/exporter/kustomization.yaml deleted file mode 100644 index 4eed917b9..000000000 --- a/kubernetes/apps/database/emqx/exporter/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# yaml-language-server: $schema=https://json.schemastore.org/kustomization -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - ./externalsecret.yaml - - ./helmrelease.yaml diff --git a/kubernetes/apps/database/emqx/ks.yaml b/kubernetes/apps/database/emqx/ks.yaml index c9955271e..2cd4cf173 100644 --- a/kubernetes/apps/database/emqx/ks.yaml +++ b/kubernetes/apps/database/emqx/ks.yaml @@ -42,27 +42,3 @@ spec: wait: true interval: 30m timeout: 5m -# --- -# # yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json -# apiVersion: kustomize.toolkit.fluxcd.io/v1 -# kind: Kustomization -# metadata: -# name: &app emqx-exporter -# namespace: flux-system -# spec: -# targetNamespace: database -# commonMetadata: -# labels: -# app.kubernetes.io/name: *app -# dependsOn: -# - name: emqx-cluster -# - name: external-secrets-stores -# path: ./kubernetes/main/apps/database/emqx/exporter -# prune: true -# sourceRef: -# kind: GitRepository -# name: home-kubernetes -# wait: false -# interval: 30m -# -# timeout: 5m