From 2b63b0ad273bd4948d04f8f53d3ccea8cc2053e7 Mon Sep 17 00:00:00 2001 From: Adriano Santos Date: Fri, 15 Dec 2023 18:28:07 -0300 Subject: [PATCH] Created flame controller manifests --- .k8s/install/manifests/clusterrole.yaml | 143 +++++++++ .../install/manifests/clusterrolebinding.yaml | 15 + .k8s/install/manifests/deployment.yaml | 72 +++++ .k8s/install/manifests/flamepool.crd.yaml | 36 +++ .k8s/install/manifests/flamepool.yaml | 31 ++ .k8s/install/manifests/flamerunner.crd.yaml | 37 +++ .../mutatingwebhookconfiguration.yaml | 28 ++ .k8s/install/manifests/namespace.yaml | 5 + .k8s/install/manifests/service.yaml | 16 + .k8s/install/manifests/serviceaccount.yaml | 8 + Makefile | 2 +- .../tasks/bonny.gen.manifest/customizer.ex | 13 +- .../bonny.gen.manifest/flame.gen.manifest.ex | 252 ++++++++++++++++ flame_k8s_controller/manifest.yaml | 284 ------------------ .../test/integration/kind-cluster.yml | 17 ++ .../test/integration/kubeconfig-test.yaml | 19 ++ 16 files changed, 691 insertions(+), 287 deletions(-) create mode 100644 .k8s/install/manifests/clusterrole.yaml create mode 100644 .k8s/install/manifests/clusterrolebinding.yaml create mode 100644 .k8s/install/manifests/deployment.yaml create mode 100644 .k8s/install/manifests/flamepool.crd.yaml create mode 100644 .k8s/install/manifests/flamepool.yaml create mode 100644 .k8s/install/manifests/flamerunner.crd.yaml create mode 100644 .k8s/install/manifests/mutatingwebhookconfiguration.yaml create mode 100644 .k8s/install/manifests/namespace.yaml create mode 100644 .k8s/install/manifests/service.yaml create mode 100644 .k8s/install/manifests/serviceaccount.yaml create mode 100644 flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/flame.gen.manifest.ex delete mode 100644 flame_k8s_controller/manifest.yaml create mode 100644 flame_k8s_controller/test/integration/kind-cluster.yml create mode 100644 flame_k8s_controller/test/integration/kubeconfig-test.yaml diff --git a/.k8s/install/manifests/clusterrole.yaml b/.k8s/install/manifests/clusterrole.yaml new file mode 100644 index 0000000..382e919 --- /dev/null +++ b/.k8s/install/manifests/clusterrole.yaml @@ -0,0 +1,143 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: flame-controller + name: flame-controller +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + - mutatingwebhookconfigurations + verbs: + - get + - list + - update + - patch + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list + - update + - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - '*' + - apiGroups: + - "" + resources: + - node + verbs: + - get + - list + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - apiGroups: + - "" + resources: + - pods + verbs: + - '*' + - apiGroups: + - "" + resources: + - secrets + verbs: + - '*' + - apiGroups: + - "" + resources: + - serviceaccount + verbs: + - '*' + - apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - '*' + - apiGroups: + - "" + resources: + - services + verbs: + - '*' + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - '*' + - apiGroups: + - apps + resources: + - deployments + verbs: + - '*' + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - '*' + - apiGroups: + - events.k8s.io + resources: + - events + verbs: + - '*' + - apiGroups: + - flame.org + resources: + - flamepools + verbs: + - '*' + - apiGroups: + - flame.org + resources: + - flamepools/status + verbs: + - '*' + - apiGroups: + - flame.org + resources: + - flamerunners + verbs: + - '*' + - apiGroups: + - flame.org + resources: + - flamerunners/status + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - role + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - '*' diff --git a/.k8s/install/manifests/clusterrolebinding.yaml b/.k8s/install/manifests/clusterrolebinding.yaml new file mode 100644 index 0000000..f7952a3 --- /dev/null +++ b/.k8s/install/manifests/clusterrolebinding.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: flame-controller + name: flame-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flame-controller +subjects: + - kind: ServiceAccount + name: flame-controller + namespace: flame diff --git a/.k8s/install/manifests/deployment.yaml b/.k8s/install/manifests/deployment.yaml new file mode 100644 index 0000000..39f48a5 --- /dev/null +++ b/.k8s/install/manifests/deployment.yaml @@ -0,0 +1,72 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + k8s-app: flame-controller + name: flame-controller + namespace: flame +spec: + replicas: 1 + selector: + matchLabels: + k8s-app: flame-controller + template: + metadata: + labels: + k8s-app: flame-controller + spec: + containers: + - env: + - name: MIX_ENV + value: prod + - name: BONNY_OPERATOR_NAME + value: flame-controller + - name: BONNY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: BONNY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: BONNY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: BONNY_POD_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + image: eigr/flame-k8s-controller:0.1.0 + name: flame-controller + ports: + - containerPort: 9001 + name: webhooks + resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 200m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1001 + volumeMounts: + - mountPath: /mnt/cert + name: certs + initContainers: + - args: + - eval + - FlameK8sController.Webhooks.bootstrap_tls(:prod, "tls-certs") + image: eigr/flame-k8s-controller:0.1.0 + name: init-certificates + serviceAccountName: flame-controller + volumes: + - name: certs + secret: + optional: true + secretName: tls-certs diff --git a/.k8s/install/manifests/flamepool.crd.yaml b/.k8s/install/manifests/flamepool.crd.yaml new file mode 100644 index 0000000..8843d09 --- /dev/null +++ b/.k8s/install/manifests/flamepool.crd.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + k8s-app: flame-controller + name: flamepools.flame.org +spec: + group: flame.org + names: + kind: FlamePool + plural: flamepools + shortNames: + - framepool + - framepools + - pool + - pools + singular: flamepool + scope: Namespaced + versions: + - deprecationWarning: + name: v1 + schema: + openAPIV3Schema: + properties: + status: + properties: + observedGeneration: + type: integer + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/.k8s/install/manifests/flamepool.yaml b/.k8s/install/manifests/flamepool.yaml new file mode 100644 index 0000000..a2bdc91 --- /dev/null +++ b/.k8s/install/manifests/flamepool.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: flame.org/v1 +kind: FlamePool +metadata: + name: default-pool + namespace: flame +spec: + podTemplate: + spec: + containers: + - env: + - name: PHX_SERVER + value: 'false' + - name: MIX_ENV + value: prod + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + resources: + requests: + cpu: 50m + memory: 128Mi diff --git a/.k8s/install/manifests/flamerunner.crd.yaml b/.k8s/install/manifests/flamerunner.crd.yaml new file mode 100644 index 0000000..15eabb1 --- /dev/null +++ b/.k8s/install/manifests/flamerunner.crd.yaml @@ -0,0 +1,37 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + k8s-app: flame-controller + name: flamerunners.flame.org +spec: + group: flame.org + names: + kind: FlameRunner + plural: flamerunners + shortNames: + - fr + - flamerunner + - flamerunners + - runner + - runners + singular: flamerunner + scope: Namespaced + versions: + - deprecationWarning: + name: v1 + schema: + openAPIV3Schema: + properties: + status: + properties: + observedGeneration: + type: integer + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/.k8s/install/manifests/mutatingwebhookconfiguration.yaml b/.k8s/install/manifests/mutatingwebhookconfiguration.yaml new file mode 100644 index 0000000..97bd7e3 --- /dev/null +++ b/.k8s/install/manifests/mutatingwebhookconfiguration.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: flame-k8s +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: flame-k8s + namespace: flame + path: /admission-review/mutating + port: 443 + failurePolicy: Ignore + matchPolicy: Equivalent + name: flame-k8s.flame.org + rules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - deployments + - statefulsets diff --git a/.k8s/install/manifests/namespace.yaml b/.k8s/install/manifests/namespace.yaml new file mode 100644 index 0000000..c78e18a --- /dev/null +++ b/.k8s/install/manifests/namespace.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: flame diff --git a/.k8s/install/manifests/service.yaml b/.k8s/install/manifests/service.yaml new file mode 100644 index 0000000..428ca06 --- /dev/null +++ b/.k8s/install/manifests/service.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: flame-controller + name: flame-controller + namespace: flame +spec: + ports: + - name: webhooks + port: 443 + protocol: TCP + targetPort: webhooks + selector: + k8s-app: flame-controller diff --git a/.k8s/install/manifests/serviceaccount.yaml b/.k8s/install/manifests/serviceaccount.yaml new file mode 100644 index 0000000..b0f2acd --- /dev/null +++ b/.k8s/install/manifests/serviceaccount.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + k8s-app: flame-controller + name: flame-controller + namespace: flame diff --git a/Makefile b/Makefile index 3fa16f0..cf16783 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ create-k8s-namespace: kubectl create ns flame generate-k8s-manifests: - cd flame_k8s_controller && MIX_ENV=prod mix deps.get && MIX_ENV=prod mix bonny.gen.manifest --image ${operator-image} --namespace flame + cd flame_k8s_controller && MIX_ENV=prod mix deps.get && MIX_ENV=prod mix flame.gen.manifest --image ${operator-image} --namespace flame --out ../.k8s/install/manifests apply-k8s-manifests: kubectl -n flame apply -f flame_k8s_controller/manifest.yaml \ No newline at end of file diff --git a/flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/customizer.ex b/flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/customizer.ex index 6bd6e55..566a200 100644 --- a/flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/customizer.ex +++ b/flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/customizer.ex @@ -21,6 +21,8 @@ defmodule Mix.Tasks.Bonny.Gen.Manifest.FlameK8sControllerCustomizer do @spec override(Bonny.Resource.t()) :: Bonny.Resource.t() def override(%{"kind" => "Deployment"} = resource) do + IO.inspect(resource, label: "Customizer Overrides") + image = get_in( resource, @@ -38,7 +40,10 @@ defmodule Mix.Tasks.Bonny.Gen.Manifest.FlameK8sControllerCustomizer do resource |> update_in( ["spec", "template", "spec", Access.key("volumes", [])], - &[%{"name" => "certs", "secret" => %{"secretName" => "tls-certs", "optional" => true}} | &1] + &[ + %{"name" => "certs", "secret" => %{"secretName" => "tls-certs", "optional" => true}} + | &1 + ] ) |> put_in( [ @@ -94,6 +99,8 @@ defmodule Mix.Tasks.Bonny.Gen.Manifest.FlameK8sControllerCustomizer do end def override(%{"kind" => "ClusterRole"} = resource) do + IO.inspect(resource, label: "Customizer Overrides") + Map.update!(resource, "rules", fn rules -> [ ~y""" @@ -114,6 +121,8 @@ defmodule Mix.Tasks.Bonny.Gen.Manifest.FlameK8sControllerCustomizer do end def override(%{"kind" => "CustomResourceDefinition"} = resource) do + IO.inspect(resource, label: "Customizer Overrides") + resource |> Map.update!("metadata", fn %{"labels" => labels} = metadata when labels == %{} -> Map.delete(metadata, "labels") @@ -132,5 +141,5 @@ defmodule Mix.Tasks.Bonny.Gen.Manifest.FlameK8sControllerCustomizer do end # fallback - def override(resource), do: resource + def override(resource), do: IO.inspect(resource, label: "Customizer Overrides") end diff --git a/flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/flame.gen.manifest.ex b/flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/flame.gen.manifest.ex new file mode 100644 index 0000000..f57c2c3 --- /dev/null +++ b/flame_k8s_controller/lib/mix/tasks/bonny.gen.manifest/flame.gen.manifest.ex @@ -0,0 +1,252 @@ +defmodule Mix.Tasks.Flame.Gen.Manifest do + use Mix.Task + + alias Bonny.Mix.Operator + alias FlameK8sController.K8sConn + alias Mix.Tasks.Bonny.Gen.Manifest.FlameK8sControllerCustomizer + + import YamlElixir.Sigil + + @default_opts [namespace: "flame"] + @switches [namespace: :string, image: :string, out: :string] + @aliases [n: :namespace, i: :image, o: :out] + + @shortdoc "Generate Kubernetes YAML manifest for this operator" + + @spec run(list()) :: :ok + def run(args) do + Mix.Task.run("compile") + + {opts, _, _} = + Mix.Bonny.parse_args(args, @default_opts, switches: @switches, aliases: @aliases) + + do_run(Mix.env(), opts) + end + + @spec do_run(atom(), Keyword.t()) :: :ok + def do_run(:prod, opts) do + out = Keyword.fetch!(opts, :out) + + generate_manifest(:prod, opts) + |> Ymlr.documents!() + |> YamlElixir.read_all_from_string!() + |> Enum.map(&FlameK8sControllerCustomizer.override/1) + |> render(out) + end + + def do_run(env, opts) when env in [:dev, :test] do + cluster_name = "flame-#{env}" + + Application.ensure_all_started(:k8s) + ensure_cluster(cluster_name, "./test/integration/kubeconfig-#{env}.yaml") + conn = K8sConn.get!(env) + ensure_namespace(conn, Keyword.fetch!(opts, :namespace)) + + operations = + generate_manifest(env, opts) + |> Ymlr.documents!() + |> YamlElixir.read_all_from_string!() + |> Enum.map(&K8s.Client.apply/1) + + errors = + conn + |> K8s.Client.async(operations) + |> Enum.reject(&match?({:ok, _}, &1)) + + if errors == [] do + Mix.Shell.IO.info("Manifest applied to cluster #{cluster_name}") + else + Mix.Shell.IO.error("Error occurred when applying manifests to cluster:") + dbg(errors) + end + + :ok + end + + @spec render(list(map()), binary()) :: :ok + defp render(documents, out) do + if File.dir?(out) do + documents + |> Ymlr.documents!() + |> YamlElixir.read_all_from_string!() + |> Enum.map(fn + %{"kind" => "CustomResourceDefinition"} = resource -> + {"#{resource["spec"]["names"]["singular"]}.crd.yaml", resource} + + resource -> + {"#{String.downcase(resource["kind"])}.yaml", resource} + end) + |> Enum.each(fn {filename, resource} -> + Mix.Bonny.render(Ymlr.document!(resource), Path.join(out, filename)) + end) + else + documents + |> Ymlr.documents!() + |> Mix.Bonny.render(out) + end + + :ok + end + + @spec ensure_cluster(cluster_name :: binary(), kubeconfig_path :: binary()) :: :ok + defp ensure_cluster(cluster_name, kubeconfig_path) do + {clusters, 0} = System.cmd("kind", ~w(get clusters)) + + if cluster_name not in String.split(clusters, "\n", trim: true) do + Mix.Shell.IO.info("Creating kind cluster #{cluster_name}") + + 0 = + Mix.Shell.IO.cmd( + "kind create cluster --name #{cluster_name} --config ./test/integration/kind-cluster.yml" + ) + end + + if not File.exists?(kubeconfig_path) do + Mix.Shell.IO.info("Generating kubeconfig file: #{kubeconfig_path}") + + 0 = + Mix.Shell.IO.cmd( + ~s(kind export kubeconfig --kubeconfig "#{kubeconfig_path}" --name "#{cluster_name}") + ) + end + + :ok + end + + @spec ensure_namespace(K8s.Conn.t(), binary()) :: :ok + defp ensure_namespace(conn, namespace) do + {:ok, _} = + K8s.Client.apply(~y""" + apiVersion: v1 + kind: Namespace + metadata: + name: #{namespace} + """) + |> K8s.Client.put_conn(conn) + |> K8s.Client.run() + + :ok + end + + @spec generate_manifest(atom(), Keyword.t()) :: list(map()) + defp generate_manifest(:prod, opts) do + image = Keyword.fetch!(opts, :image) + namespace = Keyword.fetch!(opts, :namespace) + + [ + Operator.deployment(image, namespace), + ns_manifest(namespace), + svc_manifest(namespace), + webhook_config_manifest(namespace) + | generate_manifest(:dev, opts) + ] + end + + defp generate_manifest(_, opts) do + namespace = Keyword.fetch!(opts, :namespace) + operators = Operator.find_operators() + + Operator.crds(operators) ++ + [ + Operator.cluster_role(operators), + Operator.service_account(namespace), + Operator.cluster_role_binding(namespace), + default_flame_pool(namespace) + ] + end + + @spec ns_manifest(namespace :: binary()) :: map() + def ns_manifest(namespace) do + ~y""" + apiVersion: v1 + kind: Namespace + metadata: + name: #{namespace} + """ + end + + @spec svc_manifest(namespace :: binary()) :: map() + def svc_manifest(namespace) do + ~y""" + apiVersion: v1 + kind: Service + metadata: + name: flame-controller + namespace: #{namespace} + labels: + k8s-app: flame-controller + spec: + ports: + - name: webhooks + port: 443 + targetPort: webhooks + protocol: TCP + selector: + k8s-app: flame-controller + """ + end + + @spec webhook_config_manifest(namespace :: binary()) :: map() + defp webhook_config_manifest(namespace) do + ~y""" + apiVersion: admissionregistration.k8s.io/v1 + kind: MutatingWebhookConfiguration + metadata: + name: "flame-k8s" + webhooks: + - name: "flame-k8s.flame.org" + admissionReviewVersions: ["v1"] + matchPolicy: Equivalent + rules: + - operations: ['CREATE', 'UPDATE'] + apiGroups: ['apps'] + apiVersions: ['v1'] + resources: + - deployments + - statefulsets + failurePolicy: 'Ignore' # Fail-open (optional) + clientConfig: + service: + namespace: #{namespace} + name: flame-k8s + path: /admission-review/mutating + port: 443 + """ + end + + @spec default_flame_pool(namespace :: binary()) :: map() + defp default_flame_pool(namespace) do + ~y""" + apiVersion: flame.org/v1 + kind: FlamePool + metadata: + name: default-pool + namespace: #{namespace} + spec: + podTemplate: + spec: + containers: + - env: + - name: PHX_SERVER + value: "false" + - name: MIX_ENV + value: prod + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + resources: + requests: + cpu: 50m + memory: 128Mi + """ + end +end diff --git a/flame_k8s_controller/manifest.yaml b/flame_k8s_controller/manifest.yaml deleted file mode 100644 index dd173bf..0000000 --- a/flame_k8s_controller/manifest.yaml +++ /dev/null @@ -1,284 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - k8s-app: flame-controller - name: flame-controller - namespace: flame -spec: - replicas: 1 - selector: - matchLabels: - k8s-app: flame-controller - template: - metadata: - labels: - k8s-app: flame-controller - spec: - containers: - - env: - - name: MIX_ENV - value: prod - - name: BONNY_OPERATOR_NAME - value: flame-controller - - name: BONNY_POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: BONNY_POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: BONNY_POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: BONNY_POD_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - image: eigr/flame-k8s-controller:0.1.0 - name: flame-controller - resources: - limits: - cpu: 200m - memory: 200Mi - requests: - cpu: 200m - memory: 200Mi - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65534 - serviceAccountName: flame-controller - ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - k8s-app: flame-controller - name: flamerunners.flame.org -spec: - group: flame.org - names: - kind: FlameRunner - plural: flamerunners - shortNames: - - fr - - flamerunner - - flamerunners - - runner - - runners - singular: flamerunner - scope: Namespaced - versions: - - additionalPrinterColumns: [] - deprecated: false - deprecationWarning: - name: v1 - schema: - openAPIV3Schema: - properties: - status: - properties: - observedGeneration: - type: integer - type: object - type: object - x-kubernetes-preserve-unknown-fields: true - served: true - storage: true - subresources: - status: {} - ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - k8s-app: flame-controller - name: flamepools.flame.org -spec: - group: flame.org - names: - kind: FlamePool - plural: flamepools - shortNames: - - framepool - - framepools - - pool - - pools - singular: flamepool - scope: Namespaced - versions: - - additionalPrinterColumns: [] - deprecated: false - deprecationWarning: - name: v1 - schema: - openAPIV3Schema: - properties: - status: - properties: - observedGeneration: - type: integer - type: object - type: object - x-kubernetes-preserve-unknown-fields: true - served: true - storage: true - subresources: - status: {} - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - k8s-app: flame-controller - name: flame-controller -rules: - - apiGroups: - - "" - resources: - - configmaps - verbs: - - '*' - - apiGroups: - - "" - resources: - - node - verbs: - - get - - list - - apiGroups: - - "" - resources: - - nodes - verbs: - - get - - list - - apiGroups: - - "" - resources: - - pods - verbs: - - '*' - - apiGroups: - - "" - resources: - - secrets - verbs: - - '*' - - apiGroups: - - "" - resources: - - serviceaccount - verbs: - - '*' - - apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - '*' - - apiGroups: - - "" - resources: - - services - verbs: - - '*' - - apiGroups: - - apiextensions.k8s.io - resources: - - customresourcedefinitions - verbs: - - '*' - - apiGroups: - - apps - resources: - - deployments - verbs: - - '*' - - apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - '*' - - apiGroups: - - events.k8s.io - resources: - - events - verbs: - - '*' - - apiGroups: - - flame.org - resources: - - flamepools - verbs: - - '*' - - apiGroups: - - flame.org - resources: - - flamepools/status - verbs: - - '*' - - apiGroups: - - flame.org - resources: - - flamerunners - verbs: - - '*' - - apiGroups: - - flame.org - resources: - - flamerunners/status - verbs: - - '*' - - apiGroups: - - rbac.authorization.k8s.io - resources: - - role - verbs: - - '*' - - apiGroups: - - rbac.authorization.k8s.io - resources: - - rolebindings - verbs: - - '*' - - apiGroups: - - rbac.authorization.k8s.io - resources: - - roles - verbs: - - '*' - ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - k8s-app: flame-controller - name: flame-controller - namespace: flame - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - k8s-app: flame-controller - name: flame-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: flame-controller -subjects: - - kind: ServiceAccount - name: flame-controller - namespace: flame diff --git a/flame_k8s_controller/test/integration/kind-cluster.yml b/flame_k8s_controller/test/integration/kind-cluster.yml new file mode 100644 index 0000000..c483405 --- /dev/null +++ b/flame_k8s_controller/test/integration/kind-cluster.yml @@ -0,0 +1,17 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + extraPortMappings: + - containerPort: 31436 + hostPort: 31436 + listenAddress: "127.0.0.1" + - containerPort: 31437 + hostPort: 31437 + listenAddress: "127.0.0.1" + kubeadmConfigPatches: + - | + kind: ClusterConfiguration + apiServer: + extraArgs: + enable-admission-plugins: MutatingAdmissionWebhook,ValidatingAdmissionWebhook diff --git a/flame_k8s_controller/test/integration/kubeconfig-test.yaml b/flame_k8s_controller/test/integration/kubeconfig-test.yaml new file mode 100644 index 0000000..fa91884 --- /dev/null +++ b/flame_k8s_controller/test/integration/kubeconfig-test.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +clusters: + - cluster: + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EY3lPREl4TXpJek1Gb1hEVE16TURjeU5USXhNekl6TUZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTlIyCkkvMzNYeXB0VXB5YW4wNnNLSlVsekNoR2UzZ2pkY0ZJVVRaS1JsNmk5ZVFLbjdNaWsrYzFUWmduZkdMeC9vSk4KbFpicmxSbkJkZ3gxRWtzbFhDeFZMMWdzWS9vWGx2alNidDRpZDJVeXR2d2ZscWZJWnFGQ1pjZXR3cURmcEwzNApjOC9JamRWUEFYV2JuV1BWc2kxSjBPcnFwMU5vdVY2c1QwUWZSZUtNSlFYMUhjejBGWWUzZDNUTGJIS2NEMzNrCkJydEllZlFwaE5MVWRKYjZHd0JpRnF4Q0VacGFRdmVlSlBFdS8rbXZHZXd0TGlkTWdUZHkvd2VQWlNNYUpqWTIKUXpKblNGWGRUb2l3L0tTVE1Jc1ZoZ3RPTHJJL29tS1EvVGFJRUZldm9ZN28rVm5zSmVVbnB3V0dwaEt1ck9yeQpKeXpvdDdrU2cwMW16Z3RvalprQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZIKzRRc2xUbmVCZ012L2pXOUhVamhpVDd6ak9NQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFDTmRDdmI4U0p1Q3FBallBdHJpT3MyZFVFREtzcjQyWTZzTUI1V0Nzd3o2bEJkZkt0RAozRk9HdXJLLzFFS2t5OGVrU2hid2piWjl4ZHBzdkZaQ3BJUlVaVm82ak5iK0l1NXdNOGd1TXo4Q2tCdG9lVVp2Cm1Hd00xblkrMGxhMW1hSkM5ckRIa3N5Y25WUk9EYUFYQk5Cd0hkOUFsTTBNSElSdm8zUWgwQnFOQVJ5NFBGNTgKMk1QNmMydTh3WlI1a2pycnZhQ3lrTEZjdjJYaXpkZjV0WFlTd2ZaZUN1ZUowMUhIY0ROSHJpT2d0b25HbS9jdgpjbStQVVdRZG1Rc3p4UkoxRHR5cmczazlrcDdWSWwwUE1OeFRSYThTYldweFR1VWwySkxrbGtNbXVzMVNUUGFVCkEweUJJU3YydjF3MVVrN1ZPd1pxR3MwM1h2bm90dTJ1L2FCRwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + server: https://127.0.0.1:43049 + name: kind-flame-test +contexts: + - context: + cluster: kind-flame-test + user: kind-flame-test + name: kind-flame-test +current-context: kind-kompost-test +kind: Config +preferences: {} +users: + - name: kind-flame-test + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJRGNFRjZhR0E2S293RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TXpBM01qZ3lNVE15TXpCYUZ3MHlOREEzTWpjeU1UTXlNelJhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTFpRk0wL0lQdGI2OGxWVFkKd3lGSTNmOEJ6b3Q5MElESFpFV2o4dUhXZWJ3MnlCM3E2MnUreU1EeU5lRHpPbzZEa0NqUlpyOFFnZjZINVd6UApLOUkvZzJoTk1MUkNIdkF4OUcrQ05RTmhHZ25uT3U5amhSMVpBQjVORmUyWXZpNjV0dzdnN2s4dllSdnV0cHVnCnE4TEF1TjRScms1d1RxcDRUTHliVUZQa21ad1JrYk53WmxPL1IwV0VzQ1c4cWtsU05hV2JzUHpWYVM2b2pIaUwKUkw2UFEzSTdDM2pUdCtGZ0FuVmRUQ0pkTENZUUFMQmlRVzJ5L21YeE5lNW50ZEI4UjR0c1dNaGcxc09oQlJWaApYQXZrVVV1UnhsU1RJUkJpTmVCR3Iyczh2cDdsWUFRRmZWWXpXa3FDUW1BOU5kQlk0elRHZVlBYnlQR052azdlCjFiNDFpUUlEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JSL3VFTEpVNTNnWURMLzQxdlIxSTRZays4NAp6akFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBS28wZ1R2U0N1Q3NzL0EyZ2xyYmlnTllTdU5pRVk5amF2TWlwClVwamxoZmRoRGhMTEc5Q3kxUUlmRjE3bnRvcnJhcW4rdHJKcFRsTlg4Z3hiem9aR2JEY2lENEdwTkJaVC9oN2MKcDRUREpVaFJxd0plYzJqQkZRRGwySlU5SDN0K3kyUXk0bHdrMnlRRFEwbUtvZ2IwN0poYXFxSXQxMkpMWThsbApBK05JUEY0Q20xdVM0SDJzME9FQ1hseWxrNVFMbEQ2YkFtY1lZbUtFSzl1Z1NldDlOYXBjOTdiRUxrODl5UmdqClQzZitaa2NCTDEwMjk4eC85ZWs3TUw5ZTcwWE1lSkJvSEI4Y1pmcmgxZnZRaFFQaENLbVBZNFB3eWhjZGpCd1oKYkFXWEdnRUxxOEsrNy9HOEJhdkRyYmVSMFdVMThib0drVmM1WFlUMmJCdVZNb2pTQ1E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBMWlGTTAvSVB0YjY4bFZUWXd5RkkzZjhCem90OTBJREhaRVdqOHVIV2VidzJ5QjNxCjYydSt5TUR5TmVEek9vNkRrQ2pSWnI4UWdmNkg1V3pQSzlJL2cyaE5NTFJDSHZBeDlHK0NOUU5oR2dubk91OWoKaFIxWkFCNU5GZTJZdmk2NXR3N2c3azh2WVJ2dXRwdWdxOExBdU40UnJrNXdUcXA0VEx5YlVGUGttWndSa2JOdwpabE8vUjBXRXNDVzhxa2xTTmFXYnNQelZhUzZvakhpTFJMNlBRM0k3QzNqVHQrRmdBblZkVENKZExDWVFBTEJpClFXMnkvbVh4TmU1bnRkQjhSNHRzV01oZzFzT2hCUlZoWEF2a1VVdVJ4bFNUSVJCaU5lQkdyMnM4dnA3bFlBUUYKZlZZeldrcUNRbUE5TmRCWTR6VEdlWUFieVBHTnZrN2UxYjQxaVFJREFRQUJBb0lCQUFGYVNILzJRWDhtYTA2TwpNS2hhNTNqdmlYVmlrRExtL1Z0MnpTaFZvT00zK3lpY2Q4Vnc4czJWMm5IWXIvQ293ZEFCVWdGU0o2cUtqeFUxCjhNRVlIT3FabUJNOHNFWTl3ak1IR1UxNGJmNmFIV25UNVU4TDltbjN4d2ppYlZxV05Qb2hEKzZ4ZFYwcHJnSmQKVFZDSWRHczJpK29MK00ybWFnZ2lFT0ViQnBDcDFzUzBIOFZyZ2pnd0JXWUJna25VeGhCYXN3OFk5MEpvUmE3cgpoQUIzcmRXMTI3TzlDRlRranZSYW42a3lmZTNpYmRYbmpadHRkM3ljaC82U2Nrc2cyaTE3S1RVR1U0dFVKU3FaClVBbldWcWtYRkNCWFYyS1lRMnl2WmVxeFY0aU1INjlMSkpsNkxPSERta21nQ0RyT0J4c3o1a0w1VERsMFdvR04KcFdkUVVWa0NnWUVBNFBsSU1uL1FGSVRYQ003SXZ4SmRiTXUyMW4xUkVNMmtYOVV6RU9GV1VHMWJiVGpyYXNFdApKcStSMjdEaFd4dGdOdEtSK3I5ZVdWU0s5UjJISzViTmZCS05oeCsyMEZXK1FMZUJrWnV4eElUUmhDYU5BTFJGCmwrZXA3THcvdDc1d3FtSVd5bHJ1QU5XNmZsME5YancvZlNzbExoQWtwaE5nZ2hLT2FRbDdkWWNDZ1lFQTg2a3UKV1dQZUs1RFFjTHV6WVBCTzVmUDVCdCtQR2xRWnI5emVRcjhmRjZPUzFycVp1OTZuODREb2NhUFJBZFV3WVFNMgpOREkvQkVnazBDREpvd2dLMmFtbTVsaEdaRElRTTFJNlg3eG9xRERQM3Z6Y3crN2RWRHNuSTNwdUtZMWd5cytvCkNvVGRkcE1hZnM3ZGVRdjFGbElIUlFMN2ZlYXRnN0NheEZxbndHOENnWUVBakF6alV2eWFMb3ZieVpIaENvR0cKUTFvMkFpU1ZPSjZyK3pTZnk1eGJ2VW0ycHJIT2EvRENDTmszTmNwUklBUlV5d3dlOERmOXBpS3BOcG9oTVpONQpiQW1vclR1aTlPTEx3MEg1bVFtUmlzTWNJdVpVMU9Ga2lZSWdHRTNBWk1SYkl0WlpWYk54Z25lSzEydGFEUlg0CmVCVkoyZmtXdDRSTWlleS9Wc2dlWVRVQ2dZQU12cml4N0V0ZXRBQnpKUjVJMzhrQXRqWThhYzB1YjErNGx6RDUKQk00M2lsTFA4SXJDRE85MENUWWZXNVkvSmt1VmgzbDZXWFo2WHR1dUYwajB3aUx2SjdTWEw5N2V0cytxSDQ3MgpHd0RPYTE4MEpyM1ZjZFVaNXM0eFNPSWlRa2JoMU9MUlNnbmJmZTVRMjdreDc3SXVMTFE4bzk5THdwa28zai82CkxWUEErUUtCZ1FDNmZsMFRhVjkwclJJSHVxZnN4RGwzbWc5YkdUWEJ1Z2gvT3FFOVJvZFl3V3Z3SnQram90Q24KbVdWQ2QxU3phdTJHbStoaGNpckI5ZC9iT0Y5UjFJRCt1VVZ6Q09UNDRLU0wxOEc3aXpoMWZSbGxXUDhGMWp1VApjMTJseU12K3dmYU5kN09pUmNBb3RZK2RBTlJRZXJnUUdMYW5rSTFsN1FrNkJUeHhxandhdWc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=