diff --git a/.gitea/actions/kubectl-setup/action.yml b/.gitea/actions/kubectl-setup/action.yml new file mode 100644 index 0000000..857b685 --- /dev/null +++ b/.gitea/actions/kubectl-setup/action.yml @@ -0,0 +1,45 @@ +name: Setup kubectl +description: "Reads kube config from inputs and sets KUBECONFIG" + +inputs: + kube_server: + description: "Kubernetes API server address" + required: true + kube_ca_base64: + description: "Base64-encoded CA certificate" + required: true + kube_token: + description: "ServiceAccount token" + required: true + +runs: + using: "composite" + steps: + - name: Create kubeconfig + shell: bash + run: | + set -euo pipefail + mkdir -p "${GITHUB_TEMP}/.kube" + + cat < "${GITHUB_TEMP}/.kube/config" + apiVersion: v1 + kind: Config + clusters: + - cluster: + certificate-authority-data: ${{ inputs.kube_ca_base64 }} + server: ${{ inputs.kube_server }} + name: cluster + contexts: + - context: + cluster: cluster + namespace: default + user: user + name: context + current-context: context + users: + - name: user + user: + token: ${{ inputs.kube_token }} + EOF + + echo "KUBECONFIG=${GITHUB_TEMP}/.kube/config" >> "${GITHUB_ENV}" diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml new file mode 100644 index 0000000..befe4ed --- /dev/null +++ b/.gitea/workflows/deploy.yaml @@ -0,0 +1,35 @@ +name: Casa Home Assistant CI/CD Pipeline + +on: + push: + branches: + - main + pull_request: + +jobs: + build: + runs-on: mf-casa-vlan-cid-runner + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup kubectl + uses: ./.github/actions/kubectl-setup + with: + kube_server: ${{ secrets.casa_vlan_kube_server }} + kube_ca_base64: ${{ secrets.casa_vlan_kube_ca_base64 }} + kube_token: ${{ secrets.casa_vlan_kube_token }} + + - name: Deploy Home Assistant + shell: bash + run: | + set -e + cd ${{ gitea.workspace }} + export ENDPOINT_IP="${{ secrets.ENDPOINT_IP }}" + export SERVICE_PORT=${{ secrets.SERVICE_PORT }} + export INGRESS_ROUTES_MATCH="${{ secrets.INGRESS_ROUTES_MATCH }}" + export INGRESS_TLS_SECRET_NAME=${{ secrets.INGRESS_TLS_SECRET_NAME }} + kubectl apply -f ./deploy/deployment.yaml + envsubst < ./deploy/service.template.yaml | kubectl apply -f - + + \ No newline at end of file diff --git a/README.md b/README.md index e001698..137a92d 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ All essential containers, such as MQTT and speech recognition, are hosted on the Using as Ir blaster for living room devices and temperature meter. -![ZigBee Smart Plugs](doc/images/broadlink-universal-remote-irwifi-rm4-mini.jpg) +![ZigBee Smart Plugs](./docs/images/broadlink-universal-remote-irwifi-rm4-mini.jpg) **Integrations:** @@ -51,7 +51,7 @@ Currently controlling: - dining table lights - office room lights -![ZigBee Smart Plugs](doc/images/51ojy7qoMmL._SL1500_.jpg) +![ZigBee Smart Plugs](./docs/images/51ojy7qoMmL._SL1500_.jpg) **Integrations:** @@ -68,7 +68,7 @@ Currently controlling: - shellyplug-s-80646F80FB14.dev.lan - gaia.dev.lan (proxmox server) -![Shelly - Smart Plug](doc/images/shellysmartplug.png) +![Shelly - Smart Plug](./docs/images/shellysmartplug.png) Devices connected to IOT lan. @@ -102,7 +102,7 @@ Using SONOFF Universal Zigbee 3.0 USB Dongle Plus. The [broadlink integration](https://www.home-assistant.io/integrations/broadlink) allows you to control and monitor Broadlink universal remotes, smart plugs, power strips, switches and sensors. -![broadlink integration](./doc/images/integrations-broadlink.png). +![broadlink integration](./docs/images/integrations-broadlink.png). Devices: @@ -255,5 +255,4 @@ Home Assistant authenticates with Xbox Live through OAuth2 using the Home Assist ## Setup -[Check folder setup](./setup). - +[Deploy documentation](./deploy/README.md). diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..5c335be --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,51 @@ +# Home Assistant Deploy + +## Namespace + +```bash { cwd=../ terminalRows=15 } +# from repo root folder +kubectl create namespace home-assistant +``` + +## Deployment + +### Environments requirements + +``` bash +#./deploy/.env + +export ENDPOINT_IP="xxx.xxx.xxx.xxxx" +export SERVICE_PORT=xxxx +export INGRESS_ROUTES_MATCH="Host(`xxxx`)" +export INGRESS_TLS_SECRET_NAME=xxxxxx +``` + +## Test Templates + +```bash { cwd=../ terminalRows=15 } +# from repo root folder +source ./deploy/.env \ +&& cat ./deploy/deployment.yaml \ +&& envsubst < ./deploy/service.template.yaml +``` + +## Deploy + +```bash { cwd=../ terminalRows=15 } +# from repo root folder +source ./deploy/.env \ +&& kubectl apply -f ./deploy/deployment.yaml \ +&& envsubst < ./deploy/service.template.yaml | kubectl apply -f - +``` + +## Continuos Deploy + +All Environment variables requirements as set as secrets. + +[gitea workflow](../.gitea/workflows/deploy.yaml) + +## RBAC + +```bash { cwd=../ } +kubectl apply -f ./deploy/rbac.yaml +``` diff --git a/deploy/home-assistant-deploy.yaml b/deploy/deployment.yaml similarity index 87% rename from deploy/home-assistant-deploy.yaml rename to deploy/deployment.yaml index 2381834..142b9a0 100644 --- a/deploy/home-assistant-deploy.yaml +++ b/deploy/deployment.yaml @@ -1,7 +1,3 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: home-assistant --- apiVersion: v1 @@ -38,10 +34,10 @@ spec: dnsPolicy: ClusterFirstWithHostNet # ensures pod uses cluster DNS (CoreDNS) for service discovery even with host networking hostNetwork: true # delays start so host have time to start on low memory resources - initContainers: - - name: delay-start - image: busybox:latest - command: ["sh", "-c", "sleep 60"] + # initContainers: + # - name: delay-start + # image: busybox:latest + # command: ["sh", "-c", "sleep 60"] containers: - name: home-assistant image: "homeassistant/home-assistant" diff --git a/deploy/home-assistant-external-service.yaml b/deploy/home-assistant-external-service.yaml deleted file mode 100644 index 89b7252..0000000 --- a/deploy/home-assistant-external-service.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: home-assistant-external - namespace: home-assistant -spec: - clusterIP: None - ports: - - port: 8123 - protocol: TCP - ---- - -apiVersion: v1 -kind: Endpoints -metadata: - name: home-assistant-external - namespace: home-assistant -subsets: - - addresses: - - ip: 192.168.14.9 # Replace with your actual external IP - ports: - - port: 8123 \ No newline at end of file diff --git a/deploy/home-assistant-ingress.yaml b/deploy/home-assistant-ingress.yaml deleted file mode 100644 index 259786f..0000000 --- a/deploy/home-assistant-ingress.yaml +++ /dev/null @@ -1,22 +0,0 @@ - -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: home-assistant - namespace: home-assistant -spec: - entryPoints: - - websecure - routes: - - match: Host(`casa.limbosolutions.com`) - kind: Rule - services: - - name: home-assistant-external - port: 8123 - - match: Host(`has.casa.limbosolutions.com`) - kind: Rule - services: - - name: home-assistant-external - port: 8123 - tls: - secretName: casa-limbosolutions-com-tls \ No newline at end of file diff --git a/deploy/rbac.yaml b/deploy/rbac.yaml new file mode 100644 index 0000000..e6969d2 --- /dev/null +++ b/deploy/rbac.yaml @@ -0,0 +1,34 @@ + + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: home-assistant + name: ci-cd +rules: +- apiGroups: [""] + resources: ["pods", "services", "secrets", "configmaps", "persistentvolumeclaims", "endpoints"] + verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] +- apiGroups: ["apps"] + resources: ["deployments", "statefulsets"] + verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] +- apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] +- apiGroups: ["traefik.io"] + resources: ["ingressroutes"] + verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ci-cd + namespace: home-assistant +subjects: +- kind: ServiceAccount + name: casa-ci-cd + namespace: home-assistant +roleRef: + kind: Role + name: ci-cd + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/service-account-secret.yaml b/deploy/service-account-secret.yaml new file mode 100644 index 0000000..67d37ee --- /dev/null +++ b/deploy/service-account-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: casa-ci-cd + annotations: + kubernetes.io/service-account.name: casa-ci-cd +type: kubernetes.io/service-account-token \ No newline at end of file diff --git a/deploy/service-account.yaml b/deploy/service-account.yaml new file mode 100644 index 0000000..933fa7e --- /dev/null +++ b/deploy/service-account.yaml @@ -0,0 +1,6 @@ + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: casa-ci-cd + namespace: home-assistant diff --git a/deploy/service.template.yaml b/deploy/service.template.yaml new file mode 100644 index 0000000..fed62db --- /dev/null +++ b/deploy/service.template.yaml @@ -0,0 +1,42 @@ + +apiVersion: v1 +kind: Service +metadata: + name: home-assistant + namespace: home-assistant +spec: + clusterIP: None + ports: + - port: ${SERVICE_PORT} + protocol: TCP + +--- + +apiVersion: v1 +kind: Endpoints +metadata: + name: home-assistant + namespace: home-assistant +subsets: + - addresses: + - ip: ${ENDPOINT_IP} + ports: + - port: ${SERVICE_PORT} +--- + +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: home-assistant + namespace: home-assistant +spec: + entryPoints: + - websecure + routes: + - match: ${INGRESS_ROUTES_MATCH} + kind: Rule + services: + - name: home-assistant + port: ${SERVICE_PORT} + tls: + secretName: ${INGRESS_TLS_SECRET_NAME} \ No newline at end of file diff --git a/doc/images/51ojy7qoMmL._SL1500_.jpg b/docs/images/51ojy7qoMmL._SL1500_.jpg similarity index 100% rename from doc/images/51ojy7qoMmL._SL1500_.jpg rename to docs/images/51ojy7qoMmL._SL1500_.jpg diff --git a/doc/images/broadlink-universal-remote-irwifi-rm4-mini.jpg b/docs/images/broadlink-universal-remote-irwifi-rm4-mini.jpg similarity index 100% rename from doc/images/broadlink-universal-remote-irwifi-rm4-mini.jpg rename to docs/images/broadlink-universal-remote-irwifi-rm4-mini.jpg diff --git a/doc/images/integrations-broadlink.png b/docs/images/integrations-broadlink.png similarity index 100% rename from doc/images/integrations-broadlink.png rename to docs/images/integrations-broadlink.png diff --git a/doc/images/portainer-has.png b/docs/images/portainer-has.png similarity index 100% rename from doc/images/portainer-has.png rename to docs/images/portainer-has.png diff --git a/doc/images/shellysmartplug.png b/docs/images/shellysmartplug.png similarity index 100% rename from doc/images/shellysmartplug.png rename to docs/images/shellysmartplug.png