瀏覽代碼

NAS-121476 / 23.10 / Add tailscale to `community` train (#1122)

* Add tailscale to community catalog

* mock key format
Stavros Kois 2 年之前
父節點
當前提交
4f4acbc7c7

+ 6 - 0
library/ix-dev/community/tailscale/Chart.lock

@@ -0,0 +1,6 @@
+dependencies:
+- name: common
+  repository: file://../../../common
+  version: 1.0.5
+digest: sha256:cf1db8c2ae650987a3e3d8d98767caab62c341bd0fb15309213b00dce87111cc
+generated: "2023-04-17T12:58:28.51235027+03:00"

+ 25 - 0
library/ix-dev/community/tailscale/Chart.yaml

@@ -0,0 +1,25 @@
+name: tailscale
+description: Secure remote access to shared resources
+annotations:
+  title: Tailscale
+type: application
+version: 1.0.0
+apiVersion: v2
+appVersion: 'v1.38.4'
+kubeVersion: '>=1.16.0-0'
+maintainers:
+  - name: truenas
+    url: https://www.truenas.com/
+dependencies:
+  - name: common
+    repository: file://../../../common
+    version: 1.0.5
+home: https://tailscale.com/
+icon: https://avatars.githubusercontent.com/u/48932923
+sources:
+  - https://tailscale.com/
+  - https://github.com/truenas/charts/tree/master/community/tailscale
+  - https://hub.docker.com/r/tailscale/tailscale
+keywords:
+  - vpn
+  - tailscale

+ 6 - 0
library/ix-dev/community/tailscale/README.md

@@ -0,0 +1,6 @@
+# Tailscale
+
+[Tailscale](https://tailscale.com) Secure remote access to shared resources
+
+- When `Userspace` is **disabled**, `Tailscale` will run as root, with `/dev/net/tun` device mounted from the host.
+- When `Userspace` is **enabled**, `Tailscale` will run as a non-root user.

+ 6 - 0
library/ix-dev/community/tailscale/app-readme.md

@@ -0,0 +1,6 @@
+# Tailscale
+
+[Tailscale](https://tailscale.com) Secure remote access to shared resources
+
+- When `Userspace` is **disabled**, `Tailscale` will run as root, with `/dev/net/tun` device mounted from the host.
+- When `Userspace` is **enabled**, `Tailscale` will run as a non-root user.

二進制
library/ix-dev/community/tailscale/charts/common-1.0.5.tgz


+ 20 - 0
library/ix-dev/community/tailscale/ci/basic-values.yaml

@@ -0,0 +1,20 @@
+# FIXME: Find a way to have a test key for CI testing
+tailscaleConfig:
+  authkey: 'tskey-auth-abcd123CNTRL-abcde12345abcde12345abcde12345ab'
+  hostname: 'test-host'
+  advertiseExitNode: true
+  userspace: true
+  acceptDns: true
+
+workload:
+  tailscale:
+    podSpec:
+      containers:
+        tailscale:
+          probes:
+            liveness:
+              enabled: false
+            readiness:
+              enabled: false
+            startup:
+              enabled: false

+ 4 - 0
library/ix-dev/community/tailscale/item.yaml

@@ -0,0 +1,4 @@
+icon_url: https://avatars.githubusercontent.com/u/48932923
+categories:
+  - vpn
+  - tailscale

+ 158 - 0
library/ix-dev/community/tailscale/questions.yaml

@@ -0,0 +1,158 @@
+groups:
+  - name: Tailscale Configuration
+    description: Configure Tailscale
+  - name: Network Configuration
+    description: Configure Network for Tailscale
+  - name: Resources Configuration
+    description: Configure Resources for Tailscale
+
+questions:
+  - variable: tailscaleConfig
+    label: ""
+    group: Tailscale Configuration
+    schema:
+      type: dict
+      attrs:
+        - variable: authkey
+          label: Auth Key
+          description: |
+            The auth key for Tailscale.</br>
+            Same as `--authkey` flag.
+          schema:
+            type: string
+            default: ""
+            required: true
+            private: true
+        - variable: hostname
+          label: Hostname
+          description: |
+            The hostname for Tailscale Node.</br>
+            Only lowercase letters, numbers, and hyphens are allowed.</br>
+            Same as `--hostname` flag.
+          schema:
+            type: string
+            default: "truenas-scale"
+            required: true
+        - variable: advertiseRoutes
+          label: Advertise Routes
+          description: |
+            The routes to advertise.</br>
+            Same as `--advertise-routes` flag.
+          schema:
+            type: list
+            default: []
+            items:
+              - variable: routeEntry
+                label: Route
+                schema:
+                  type: string
+                  required: true
+        - variable: advertiseExitNode
+          label: Advertise Exit Node
+          description: |
+            Advertise as Exit Node.</br>
+            Same as `--advertise-exit-node` flag.
+          schema:
+            type: boolean
+            default: false
+        - variable: userspace
+          label: Userspace
+          description: Userspace for Tailscale.
+          schema:
+            type: boolean
+            default: true
+        - variable: acceptDns
+          label: Accept DNS
+          description: |
+            Accept DNS.</br>
+            Same as `--accept-dns` flag.
+          schema:
+            type: boolean
+            default: false
+        - variable: extraArgs
+          label: Extra Arguments
+          description: Extra arguments for Tailscale.
+          schema:
+            type: list
+            default: []
+            items:
+              - variable: argEntry
+                label: Argument
+                schema:
+                  type: string
+                  required: true
+        - variable: extraDaemonArgs
+          label: Extra Daemon Arguments
+          description: Extra arguments for Tailscale daemon.
+          schema:
+            type: list
+            default: []
+            items:
+              - variable: DaemonArgEntry
+                label: Daemon Argument
+                schema:
+                  type: string
+                  required: true
+
+        - variable: additionalEnvs
+          label: Additional Environment Variables
+          description: Configure additional environment variables for Tailscale.
+          schema:
+            type: list
+            default: []
+            items:
+              - variable: env
+                label: Environment Variable
+                schema:
+                  type: dict
+                  attrs:
+                    - variable: name
+                      label: Name
+                      schema:
+                        type: string
+                        required: true
+                    - variable: value
+                      label: Value
+                      schema:
+                        type: string
+                        required: true
+
+  - variable: tailscaleNetwork
+    label: ""
+    group: Network Configuration
+    schema:
+      type: dict
+      attrs:
+        - variable: hostNetwork
+          label: Host Network
+          description: |
+            Bind to the host network. It's recommended to keep this disabled.</br>
+          schema:
+            type: boolean
+            default: false
+
+  - variable: resources
+    group: Resources Configuration
+    label: ""
+    schema:
+      type: dict
+      attrs:
+        - variable: limits
+          label: Limits
+          schema:
+            type: dict
+            attrs:
+              - variable: cpu
+                label: CPU
+                description: CPU limit for Tailscale.
+                schema:
+                  type: string
+                  default: "4000m"
+                  required: true
+              - variable: memory
+                label: Memory
+                description: Memory limit for Tailscale.
+                schema:
+                  type: string
+                  default: "8Gi"
+                  required: true

+ 1 - 0
library/ix-dev/community/tailscale/templates/NOTES.txt

@@ -0,0 +1 @@
+{{ include "ix.v1.common.lib.chart.notes" $ }}

+ 32 - 0
library/ix-dev/community/tailscale/templates/_helper.tpl

@@ -0,0 +1,32 @@
+{{- define "tailscale.args" -}}
+  {{- $args := list -}}
+
+  {{- with .Values.tailscaleConfig.hostname -}}
+    {{- $args = mustAppend $args (printf "--hostname %v" .) -}}
+  {{- end -}}
+
+  {{- with .Values.tailscaleConfig.advertiseExitNode -}}
+    {{- $args = mustAppend $args "--advertise-exit-node" -}}
+  {{- end -}}
+
+  {{- with .Values.tailscaleConfig.extraArgs -}}
+    {{- $args = mustAppend $args . -}}
+  {{- end -}}
+
+  {{- if $args -}}
+    {{- $args | join " " -}}
+  {{- end -}}
+{{- end -}}
+
+{{- define "tailscale.validation" -}}
+  {{- if not .Values.tailscaleConfig.authkey -}}
+    {{- fail "Tailscale - Expected non-empty [Auth Key]" -}}
+  {{- end -}}
+
+  {{- with .Values.tailscaleConfig.hostname -}}
+    {{- if not (mustRegexMatch "^[a-z0-9-]+$" .) -}}
+      {{- fail "Tailscale - Expected [Hostname] to match the following - [All lowercase, numbers, dashes, No spaces, No underscores]" -}}
+    {{- end -}}
+  {{- end -}}
+
+{{- end -}}

+ 138 - 0
library/ix-dev/community/tailscale/templates/_tailscale.tpl

@@ -0,0 +1,138 @@
+{{- define "tailscale.workload" -}}
+{{ include "tailscale.validation" $ }}
+workload:
+  tailscale:
+    enabled: true
+    primary: true
+    type: Deployment
+    podSpec:
+      automountServiceAccountToken: true
+      hostNetwork: {{ .Values.tailscaleNetwork.hostNetwork }}
+      sysctls:
+        - name: net.ipv4.ip_forward
+          value: "1"
+        - name: net.ipv6.conf.all.forwarding
+          value: "1"
+      containers:
+        tailscale:
+          enabled: true
+          primary: true
+          imageSelector: image
+          command: /usr/local/bin/containerboot
+          securityContext:
+            {{ if .Values.tailscaleConfig.userspace }}
+            runAsUser: 568
+            runAsGroup: 568
+            {{ else }}
+            runAsUser: 0
+            runAsGroup: 0
+            runAsNonRoot: false
+            {{ end }}
+            readOnlyRootFilesystem: false
+            capabilities:
+              add:
+                - NET_ADMIN
+                - NET_RAW
+          env:
+            TS_KUBE_SECRET: {{ printf "%s-tailscale-secret" (include "ix.v1.common.lib.chart.names.fullname" .) }}
+            TS_SOCKET: /var/run/tailscale/tailscaled.sock
+            TS_USERSPACE: {{ .Values.tailscaleConfig.userspace | quote }}
+            TS_ACCEPT_DNS: {{ .Values.tailscaleConfig.acceptDns | quote }}
+            {{ with .Values.tailscaleConfig.advertiseRoutes }}
+            TS_ROUTES: {{ join "," . }}
+            {{ end }}
+            {{ with (include "tailscale.args" $) }}
+            TS_EXTRA_ARGS: {{ . }}
+            {{ end }}
+            {{ with .Values.tailscaleConfig.extraDaemonArgs }}
+            TS_TAILSCALED_ARGS: {{ join " " . }}
+            {{ end }}
+          {{ with .Values.tailscaleConfig.additionalEnvs }}
+          envList:
+            {{ range $env := . }}
+            - name: {{ $env.name }}
+              value: {{ $env.value }}
+            {{ end }}
+          {{ end }}
+          probes:
+            liveness:
+              enabled: true
+              type: exec
+              command:
+                - tailscale
+                - status
+            readiness:
+              enabled: true
+              type: exec
+              command:
+                - tailscale
+                - status
+            startup:
+              enabled: true
+              type: exec
+              command:
+                - tailscale
+                - status
+
+{{/* RBAC */}}
+serviceAccount:
+  tailscale:
+    enabled: true
+    primary: true
+
+rbac:
+  tailscale:
+    enabled: true
+    primary: true
+    rules:
+      - apiGroups:
+          - ""
+        resources:
+          - secrets
+        verbs:
+          - create
+      - apiGroups:
+          - ""
+        resources:
+          - secrets
+        resourceNames:
+          - {{ printf "%s-tailscale-secret" (include "ix.v1.common.lib.chart.names.fullname" .) }}
+        verbs:
+          - get
+          - update
+          - patch
+
+{{/* Persistence */}}
+persistence:
+  tun-dev:
+    enabled: {{ not .Values.tailscaleConfig.userspace }}
+    type: device
+    hostPath: /dev/net/tun
+    targetSelector:
+      tailscale:
+        tailscale:
+          mountPath: /dev/net/tun
+  var-run:
+    enabled: true
+    type: emptyDir
+    targetSelector:
+      tailscale:
+        tailscale:
+          mountPath: /var/run
+  cache:
+    enabled: true
+    type: emptyDir
+    targetSelector:
+      tailscale:
+        tailscale:
+          mountPath: /.cache
+
+{{/* Secret */}}
+secret:
+  tailscale-secret:
+    enabled: true
+    data:
+      {{/* Name "authkey" must not be changed, it's what tailscale looks for */}}
+      authkey: {{ .Values.tailscaleConfig.authkey }}
+
+{{- end -}}

+ 6 - 0
library/ix-dev/community/tailscale/templates/common.yaml

@@ -0,0 +1,6 @@
+{{- include "ix.v1.common.loader.init" . -}}
+
+{{/* Merge the templates with Values */}}
+{{- $_ := mustMergeOverwrite .Values (include "tailscale.workload" $ | fromYaml) -}}
+
+{{- include "ix.v1.common.loader.apply" . -}}

+ 1 - 0
library/ix-dev/community/tailscale/upgrade_info.json

@@ -0,0 +1 @@
+{"filename": "values.yaml", "keys": ["image"]}

+ 31 - 0
library/ix-dev/community/tailscale/upgrade_strategy

@@ -0,0 +1,31 @@
+#!/usr/bin/python3
+import json
+import re
+import sys
+
+from catalog_update.upgrade_strategy import semantic_versioning
+
+# Minor part of version is considered "stable" when it is an even number
+RE_STABLE_VERSION = re.compile(r'[0-9]+\.[0-9]+[02468]+\.[0-9]+')
+
+
+def newer_mapping(image_tags):
+    key = list(image_tags.keys())[0]
+    tags = {t: t for t in image_tags[key] if RE_STABLE_VERSION.fullmatch(t)}
+    version = semantic_versioning(list(tags))
+    if not version:
+        return {}
+
+    return {
+        'tags': {key: tags[version]},
+        'app_version': version,
+    }
+
+
+if __name__ == '__main__':
+    try:
+        versions_json = json.loads(sys.stdin.read())
+    except ValueError:
+        raise ValueError('Invalid json specified')
+
+    print(json.dumps(newer_mapping(versions_json)))

+ 23 - 0
library/ix-dev/community/tailscale/values.yaml

@@ -0,0 +1,23 @@
+image:
+  repository: tailscale/tailscale
+  pullPolicy: IfNotPresent
+  tag: 'v1.38.4'
+
+resources:
+  limits:
+    cpu: 4000m
+    memory: 8Gi
+
+tailscaleConfig:
+  authkey: ''
+  hostname: ''
+  advertiseRoutes: []
+  advertiseExitNode: false
+  userspace: true
+  acceptDns: false
+  extraArgs: []
+  extraDaemonArgs: []
+  additionalEnvs: []
+
+tailscaleNetwork:
+  hostNetwork: false