From 6ddff7c43359418c0e3be8599468a1c19f3cfa5a724707b471bcd46c61a447bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=9F=E9=85=8C=20=E9=B5=AC=E5=85=84?= Date: Mon, 20 Apr 2026 02:50:04 +0800 Subject: [PATCH] Drafting ctl controller --- README.md | 8 - clitools/devtools/gen-admission-payload.sh | 52 +++ clitools/devtools/run-controller.sh | 17 + clitools/go.mod | 62 ++- clitools/go.sum | 231 ++++++---- clitools/hack/boilerplate.go.txt | 1 + clitools/hack/tool.go | 9 + clitools/hack/update-codegen.sh | 36 ++ .../monok8s/v1alpha1/groupversion_info.go | 13 +- .../pkg/apis/monok8s/v1alpha1/monoksconfig.go | 1 - .../pkg/apis/monok8s/v1alpha1/osupgrade.go | 108 ++--- .../monok8s/v1alpha1/zz_generated.deepcopy.go | 411 ++++++++++++++++++ clitools/pkg/cmd/agent/agent.go | 241 +++++----- clitools/pkg/cmd/controller/controller.go | 97 +++++ clitools/pkg/cmd/root/root.go | 2 + clitools/pkg/controller/admission/server.go | 157 +++++++ clitools/pkg/controller/osupgrade/handler.go | 53 ++- clitools/pkg/controller/osupgrade/progress.go | 27 ++ .../clientset/versioned/clientset.go | 106 +++++ .../versioned/fake/clientset_generated.go | 91 ++++ .../generated/clientset/versioned/fake/doc.go | 6 + .../clientset/versioned/fake/register.go | 42 ++ .../clientset/versioned/scheme/doc.go | 6 + .../clientset/versioned/scheme/register.go | 42 ++ .../versioned/typed/monok8s/v1alpha1/doc.go | 6 + .../typed/monok8s/v1alpha1/fake/doc.go | 6 + .../v1alpha1/fake/fake_monok8s_client.go | 30 ++ .../monok8s/v1alpha1/fake/fake_osupgrade.go | 36 ++ .../v1alpha1/fake/fake_osupgradeprogress.go | 38 ++ .../monok8s/v1alpha1/generated_expansion.go | 9 + .../typed/monok8s/v1alpha1/monok8s_client.go | 92 ++++ .../typed/monok8s/v1alpha1/osupgrade.go | 56 +++ .../monok8s/v1alpha1/osupgradeprogress.go | 56 +++ .../informers/externalversions/factory.go | 249 +++++++++++ .../informers/externalversions/generic.go | 50 +++ .../internalinterfaces/factory_interfaces.go | 26 ++ .../externalversions/monok8s/interface.go | 32 ++ .../monok8s/v1alpha1/interface.go | 38 ++ .../monok8s/v1alpha1/osupgrade.go | 88 ++++ .../monok8s/v1alpha1/osupgradeprogress.go | 88 ++++ .../monok8s/v1alpha1/expansion_generated.go | 21 + .../listers/monok8s/v1alpha1/osupgrade.go | 56 +++ .../monok8s/v1alpha1/osupgradeprogress.go | 56 +++ clitools/pkg/kube/clients.go | 18 +- clitools/pkg/node/admission.go | 400 +++++++++++++++++ clitools/pkg/node/agent.go | 53 ++- clitools/pkg/node/kubeadm.go | 49 +++ clitools/pkg/node/metadata.go | 14 +- clitools/pkg/templates/templates.go | 3 +- clitools/pkg/templates/values.go | 7 - configs/cluster.env.default | 3 +- devtools/test-upgrade.sh | 41 ++ 52 files changed, 3093 insertions(+), 347 deletions(-) create mode 100755 clitools/devtools/gen-admission-payload.sh create mode 100755 clitools/devtools/run-controller.sh create mode 100644 clitools/hack/boilerplate.go.txt create mode 100644 clitools/hack/tool.go create mode 100755 clitools/hack/update-codegen.sh create mode 100644 clitools/pkg/apis/monok8s/v1alpha1/zz_generated.deepcopy.go create mode 100644 clitools/pkg/cmd/controller/controller.go create mode 100644 clitools/pkg/controller/admission/server.go create mode 100644 clitools/pkg/generated/clientset/versioned/clientset.go create mode 100644 clitools/pkg/generated/clientset/versioned/fake/clientset_generated.go create mode 100644 clitools/pkg/generated/clientset/versioned/fake/doc.go create mode 100644 clitools/pkg/generated/clientset/versioned/fake/register.go create mode 100644 clitools/pkg/generated/clientset/versioned/scheme/doc.go create mode 100644 clitools/pkg/generated/clientset/versioned/scheme/register.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/doc.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/doc.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_monok8s_client.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgrade.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgradeprogress.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/generated_expansion.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/monok8s_client.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgrade.go create mode 100644 clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgradeprogress.go create mode 100644 clitools/pkg/generated/informers/externalversions/factory.go create mode 100644 clitools/pkg/generated/informers/externalversions/generic.go create mode 100644 clitools/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go create mode 100644 clitools/pkg/generated/informers/externalversions/monok8s/interface.go create mode 100644 clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/interface.go create mode 100644 clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgrade.go create mode 100644 clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgradeprogress.go create mode 100644 clitools/pkg/generated/listers/monok8s/v1alpha1/expansion_generated.go create mode 100644 clitools/pkg/generated/listers/monok8s/v1alpha1/osupgrade.go create mode 100644 clitools/pkg/generated/listers/monok8s/v1alpha1/osupgradeprogress.go create mode 100644 clitools/pkg/node/admission.go create mode 100755 devtools/test-upgrade.sh diff --git a/README.md b/README.md index 663fb63..3c2ef7c 100644 --- a/README.md +++ b/README.md @@ -86,11 +86,3 @@ make cluster-config \ ``` Check inside [configs/cluster.env.default](configs/cluster.env.default) for configuration details - -### Making sub stages -```bash -make build-base # The image that builds the kernel and everything -make kernel # Builds our kernel from NXP -make initramfs -make itb # Builds out/board.itb (contains the kernel and the initramfs) -``` diff --git a/clitools/devtools/gen-admission-payload.sh b/clitools/devtools/gen-admission-payload.sh new file mode 100755 index 0000000..7b0232f --- /dev/null +++ b/clitools/devtools/gen-admission-payload.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Example: pipe this into curl +# ../../devtools/test-upgrade.sh \ +# | this_script +# | curl -k -H 'Content-Type: application/json' --data-binary @- https://127.0.0.1:8443/admission + +set -euo pipefail + +uid=$(uuidgen 2>/dev/null) + +yq -o=json '.' | jq --arg uid "$uid" ' +{ + apiVersion: "admission.k8s.io/v1", + kind: "AdmissionReview", + request: { + uid: $uid, + kind: { + group: "monok8s.io", + version: "v1alpha1", + kind: "OSUpgrade" + }, + resource: { + group: "monok8s.io", + version: "v1alpha1", + resource: "osupgrades" + }, + requestKind: { + group: "monok8s.io", + version: "v1alpha1", + kind: "OSUpgrade" + }, + requestResource: { + group: "monok8s.io", + version: "v1alpha1", + resource: "osupgrades" + }, + name: .metadata.name, + namespace: (.metadata.namespace // ""), + operation: "CREATE", + userInfo: { + username: "debug-user" + }, + object: ., + oldObject: null, + dryRun: false, + options: { + apiVersion: "meta.k8s.io/v1", + kind: "CreateOptions" + } + } +}' diff --git a/clitools/devtools/run-controller.sh b/clitools/devtools/run-controller.sh new file mode 100755 index 0000000..395b2f1 --- /dev/null +++ b/clitools/devtools/run-controller.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" +PROJ_ROOT="$( realpath "$SCRIPT_DIR"/../ )" +OUT_DIR="$PROJ_ROOT"/out + +if [ -f "$OUT_DIR/tls.key" ] && [ -f "$OUT_DIR/tls.crt" ]; then + echo "Use existing certs" +else + echo "Generating self signed certs" + openssl req -x509 -newkey rsa:2048 -nodes -days 365 \ + -keyout "$OUT_DIR"/tls.key -out "$OUT_DIR"/tls.crt \ + -subj "/CN=127.0.0.1" \ + -addext "subjectAltName=IP:127.0.0.1,DNS:localhost" +fi + +go run "$PROJ_ROOT"/cmd/ctl controller --tls-cert-file "$OUT_DIR"/tls.crt --tls-private-key-file "$OUT_DIR"/tls.key diff --git a/clitools/go.mod b/clitools/go.mod index 97076d2..d3b012c 100644 --- a/clitools/go.mod +++ b/clitools/go.mod @@ -3,31 +3,37 @@ module example.com/monok8s go 1.26.0 require ( + github.com/emicklei/go-restful/v3 v3.12.2 github.com/klauspost/compress v1.18.5 - github.com/spf13/cobra v1.9.1 - golang.org/x/sys v0.31.0 + github.com/spf13/cobra v1.10.2 + golang.org/x/sys v0.39.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.34.0 - k8s.io/apiextensions-apiserver v0.34.0 - k8s.io/apimachinery v0.34.0 + k8s.io/api v0.35.0 + k8s.io/apiextensions-apiserver v0.35.0 + k8s.io/apimachinery v0.35.0 + k8s.io/apiserver v0.35.0 k8s.io/cli-runtime v0.34.0 - k8s.io/client-go v0.34.0 + k8s.io/client-go v0.35.0 + k8s.io/code-generator v0.35.0 k8s.io/klog/v2 v2.130.1 + sigs.k8s.io/controller-tools v0.20.1 sigs.k8s.io/yaml v1.6.0 ) require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-errors/errors v1.4.2 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect + github.com/gobuffalo/flect v1.0.3 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -37,30 +43,42 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/pflag v1.0.6 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sync v0.12.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.9.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + golang.org/x/tools v0.40.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/component-base v0.35.0 // indirect + k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/clitools/go.sum b/clitools/go.sum index 5f0d86e..5d1b5f7 100644 --- a/clitools/go.sum +++ b/clitools/go.sum @@ -1,7 +1,19 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= @@ -11,12 +23,20 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= @@ -27,29 +47,31 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= +github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= +github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -59,10 +81,17 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -75,25 +104,38 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= +github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM= +github.com/onsi/gomega v1.38.3/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -104,92 +146,115 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= -golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= +golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= +google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE= -k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug= -k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc= -k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0= -k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0= -k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= +k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= +k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4= +k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= +k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/apiserver v0.35.0 h1:CUGo5o+7hW9GcAEF3x3usT3fX4f9r8xmgQeCBDaOgX4= +k8s.io/apiserver v0.35.0/go.mod h1:QUy1U4+PrzbJaM3XGu2tQ7U9A4udRRo5cyxkFX0GEds= k8s.io/cli-runtime v0.34.0 h1:N2/rUlJg6TMEBgtQ3SDRJwa8XyKUizwjlOknT1mB2Cw= k8s.io/cli-runtime v0.34.0/go.mod h1:t/skRecS73Piv+J+FmWIQA2N2/rDjdYSQzEE67LUUs8= -k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo= -k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= +k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= +k8s.io/code-generator v0.35.0 h1:TvrtfKYZTm9oDF2z+veFKSCcgZE3Igv0svY+ehCmjHQ= +k8s.io/code-generator v0.35.0/go.mod h1:iS1gvVf3c/T71N5DOGYO+Gt3PdJ6B9LYSvIyQ4FHzgc= +k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94= +k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0= +k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ= +k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-tools v0.20.1 h1:gkfMt9YodI0K85oT8rVi80NTXO/kDmabKR5Ajn5GYxs= +sigs.k8s.io/controller-tools v0.20.1/go.mod h1:b4qPmjGU3iZwqn34alUU5tILhNa9+VXK+J3QV0fT/uU= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78= diff --git a/clitools/hack/boilerplate.go.txt b/clitools/hack/boilerplate.go.txt new file mode 100644 index 0000000..c71e0e1 --- /dev/null +++ b/clitools/hack/boilerplate.go.txt @@ -0,0 +1 @@ +/* MIT License */ diff --git a/clitools/hack/tool.go b/clitools/hack/tool.go new file mode 100644 index 0000000..0c55f3a --- /dev/null +++ b/clitools/hack/tool.go @@ -0,0 +1,9 @@ +//go:build tools +// +build tools + +package tools + +import ( + _ "k8s.io/code-generator" + _ "sigs.k8s.io/controller-tools/cmd/controller-gen" +) diff --git a/clitools/hack/update-codegen.sh b/clitools/hack/update-codegen.sh new file mode 100755 index 0000000..687a386 --- /dev/null +++ b/clitools/hack/update-codegen.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -euo pipefail + +MODULE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +echo "MODULE ROOT: ${MODULE_ROOT}" + +cd "${MODULE_ROOT}" +mkdir -p \ + "${MODULE_ROOT}/pkg/generated/clientset" \ + "${MODULE_ROOT}/pkg/generated/listers" \ + "${MODULE_ROOT}/pkg/generated/informers" + +controller-gen \ + object:headerFile=hack/boilerplate.go.txt \ + paths=./pkg/apis/... + +MODULE="$(go list -m -f '{{.Path}}')" +echo "MODULE: ${MODULE}" + +CODEGEN_PKG="$(go list -f '{{.Dir}}' -m k8s.io/code-generator)" +echo "CODEGEN PKG: ${CODEGEN_PKG}" + +source "${CODEGEN_PKG}/kube_codegen.sh" + +mkdir -p "${MODULE_ROOT}/pkg/generated" + +kube::codegen::gen_helpers \ + --boilerplate "${MODULE_ROOT}/hack/boilerplate.go.txt" \ + "${MODULE_ROOT}/pkg/apis" + +kube::codegen::gen_client \ + --with-watch \ + --output-dir "${MODULE_ROOT}/pkg/generated" \ + --output-pkg "${MODULE}/pkg/generated" \ + --boilerplate "${MODULE_ROOT}/hack/boilerplate.go.txt" \ + "${MODULE_ROOT}/pkg/apis" diff --git a/clitools/pkg/apis/monok8s/v1alpha1/groupversion_info.go b/clitools/pkg/apis/monok8s/v1alpha1/groupversion_info.go index 948cef2..31a05cc 100644 --- a/clitools/pkg/apis/monok8s/v1alpha1/groupversion_info.go +++ b/clitools/pkg/apis/monok8s/v1alpha1/groupversion_info.go @@ -14,7 +14,6 @@ var ( APIVersion = "monok8s.io/v1alpha1" AltPartDeviceLink = "/dev/mksaltpart" - Annotation = "monok8s.io/annotation" BootStateFile = "/run/monok8s/boot-state.env" CatalogURL = "https://example.com/monok8s.io/v1alpha1/catalog.yaml" ControlAgentKey = "monok8s.io/control-agent" @@ -25,18 +24,20 @@ var ( ) var ( - GroupVersion = schema.GroupVersion{Group: Group, Version: Version} - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - AddToScheme = SchemeBuilder.AddToScheme + SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme ) func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(GroupVersion, + scheme.AddKnownTypes(SchemeGroupVersion, &MonoKSConfig{}, &MonoKSConfigList{}, &OSUpgrade{}, &OSUpgradeList{}, + &OSUpgradeProgress{}, + &OSUpgradeProgressList{}, ) - metav1.AddToGroupVersion(scheme, GroupVersion) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } diff --git a/clitools/pkg/apis/monok8s/v1alpha1/monoksconfig.go b/clitools/pkg/apis/monok8s/v1alpha1/monoksconfig.go index 758af8e..e9d330d 100644 --- a/clitools/pkg/apis/monok8s/v1alpha1/monoksconfig.go +++ b/clitools/pkg/apis/monok8s/v1alpha1/monoksconfig.go @@ -40,7 +40,6 @@ type MonoKSConfigSpec struct { KubeProxyNodePortAddresses []string `json:"kubeProxyNodePortAddresses,omitempty" yaml:"kubeProxyNodePortAddresses,omitempty"` SubjectAltNames []string `json:"subjectAltNames,omitempty" yaml:"subjectAltNames,omitempty"` NodeLabels map[string]string `json:"nodeLabels,omitempty" yaml:"nodeLabels,omitempty"` - NodeAnnotations map[string]string `json:"nodeAnnotations,omitempty" yaml:"nodeAnnotations,omitempty"` Network NetworkSpec `json:"network,omitempty" yaml:"network,omitempty"` } diff --git a/clitools/pkg/apis/monok8s/v1alpha1/osupgrade.go b/clitools/pkg/apis/monok8s/v1alpha1/osupgrade.go index fee1d86..a0f8881 100644 --- a/clitools/pkg/apis/monok8s/v1alpha1/osupgrade.go +++ b/clitools/pkg/apis/monok8s/v1alpha1/osupgrade.go @@ -2,7 +2,6 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" ) type OSUpgradePhase string @@ -28,6 +27,7 @@ const ( OSUpgradeProgressPhaseRejected OSUpgradeProgressPhase = "rejected" ) +// +genclient // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:scope=Namespaced,shortName=osu @@ -52,46 +52,22 @@ type OSUpgradeList struct { Items []OSUpgrade `json:"items" yaml:"items"` } -// OSUpgradeSpec defines the desired state of an OSUpgrade. type OSUpgradeSpec struct { - // DesiredVersion is the requested target version. - // - // It may be either: - // - "stable" to use the catalog's current stable version - // - an explicit version such as "v1.35.3" - // - // The resolved target version is reported in status. // +kubebuilder:validation:MinLength=1 DesiredVersion string `json:"desiredVersion,omitempty" yaml:"desiredVersion,omitempty"` - // FlashProfile controls how aggressively the image is written to disk. - // - // Supported values are: - // - "fast": prioritize speed - // - "balanced": default tradeoff between speed and system impact - // - "safe": minimize I/O pressure on the node - // - // If unset, the controller should use a default profile. // +kubebuilder:validation:Enum=fast;balanced;safe // +kubebuilder:default=balanced - FlashProfile string `json:"flashProfile,omitempty"` + FlashProfile string `json:"flashProfile,omitempty" yaml:"flashProfile,omitempty"` - // Catalog specifies how available versions and images are resolved. - // - // This may point to a remote catalog, inline catalog data, or another source, - // depending on the VersionCatalogSource definition. - Catalog *VersionCatalogSource `json:"catalog,omitempty"` - - // NodeSelector limits the upgrade to nodes whose labels match this selector. - // - // If unset, the upgrade applies to all eligible nodes. + Catalog *VersionCatalogSource `json:"catalog,omitempty" yaml:"catalog,omitempty"` NodeSelector *metav1.LabelSelector `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` } type VersionCatalogSource struct { - URL string `json:"url,omitempty"` - Inline string `json:"inline,omitempty"` - ConfigMap string `json:"configMapRef,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + Inline string `json:"inline,omitempty" yaml:"inline,omitempty"` + ConfigMap string `json:"configMapRef,omitempty" yaml:"configMapRef,omitempty"` } type OSUpgradeStatus struct { @@ -100,10 +76,8 @@ type OSUpgradeStatus struct { ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` Summary OSUpgradeSummary `json:"summary,omitempty" yaml:"summary,omitempty"` Conditions []metav1.Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` - - // Optional, useful when rejected. - Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` - Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` } type OSUpgradeSummary struct { @@ -114,6 +88,7 @@ type OSUpgradeSummary struct { FailedNodes int32 `json:"failedNodes,omitempty" yaml:"failedNodes,omitempty"` } +// +genclient // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:scope=Namespaced,shortName=osup @@ -143,56 +118,23 @@ type OSUpgradeProgressSpec struct { } type OSUpgradeSourceRef struct { - Name string `json:"name,omitempty" yaml:"name,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` } type OSUpgradeProgressStatus struct { - CurrentVersion string `json:"currentVersion,omitempty" yaml:"currentVersion,omitempty"` - TargetVersion string `json:"targetVersion,omitempty" yaml:"targetVersion,omitempty"` - Phase OSUpgradeProgressPhase `json:"phase,omitempty" yaml:"phase,omitempty"` - - StartedAt *metav1.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` - CompletedAt *metav1.Time `json:"completedAt,omitempty" yaml:"completedAt,omitempty"` - LastUpdatedAt *metav1.Time `json:"lastUpdatedAt,omitempty" yaml:"lastUpdatedAt,omitempty"` - RetryCount int32 `json:"retryCount,omitempty" yaml:"retryCount,omitempty"` - InactivePartition string `json:"inactivePartition,omitempty" yaml:"inactivePartition,omitempty"` - FailureReason string `json:"failureReason,omitempty" yaml:"failureReason,omitempty"` - Message string `json:"message,omitempty" yaml:"message,omitempty"` - - PlannedPath []string `json:"plannedPath,omitempty"` - CurrentStep int32 `json:"currentStep,omitempty"` - CurrentFrom string `json:"currentFrom,omitempty"` - CurrentTo string `json:"currentTo,omitempty"` -} - -func (in *OSUpgrade) DeepCopyObject() runtime.Object { - if in == nil { - return nil - } - out := *in - return &out -} - -func (in *OSUpgradeList) DeepCopyObject() runtime.Object { - if in == nil { - return nil - } - out := *in - return &out -} - -func (in *OSUpgradeProgress) DeepCopyObject() runtime.Object { - if in == nil { - return nil - } - out := *in - return &out -} - -func (in *OSUpgradeProgressList) DeepCopyObject() runtime.Object { - if in == nil { - return nil - } - out := *in - return &out + CurrentVersion string `json:"currentVersion,omitempty" yaml:"currentVersion,omitempty"` + TargetVersion string `json:"targetVersion,omitempty" yaml:"targetVersion,omitempty"` + Phase OSUpgradeProgressPhase `json:"phase,omitempty" yaml:"phase,omitempty"` + StartedAt *metav1.Time `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` + CompletedAt *metav1.Time `json:"completedAt,omitempty" yaml:"completedAt,omitempty"` + LastUpdatedAt *metav1.Time `json:"lastUpdatedAt,omitempty" yaml:"lastUpdatedAt,omitempty"` + RetryCount int32 `json:"retryCount,omitempty" yaml:"retryCount,omitempty"` + InactivePartition string `json:"inactivePartition,omitempty" yaml:"inactivePartition,omitempty"` + FailureReason string `json:"failureReason,omitempty" yaml:"failureReason,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + PlannedPath []string `json:"plannedPath,omitempty" yaml:"plannedPath,omitempty"` + CurrentStep int32 `json:"currentStep,omitempty" yaml:"currentStep,omitempty"` + CurrentFrom string `json:"currentFrom,omitempty" yaml:"currentFrom,omitempty"` + CurrentTo string `json:"currentTo,omitempty" yaml:"currentTo,omitempty"` } diff --git a/clitools/pkg/apis/monok8s/v1alpha1/zz_generated.deepcopy.go b/clitools/pkg/apis/monok8s/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000..df833d7 --- /dev/null +++ b/clitools/pkg/apis/monok8s/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,411 @@ +//go:build !ignore_autogenerated + +/* MIT License */ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonoKSConfig) DeepCopyInto(out *MonoKSConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(MonoKSConfigStatus) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonoKSConfig. +func (in *MonoKSConfig) DeepCopy() *MonoKSConfig { + if in == nil { + return nil + } + out := new(MonoKSConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonoKSConfigList) DeepCopyInto(out *MonoKSConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MonoKSConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonoKSConfigList. +func (in *MonoKSConfigList) DeepCopy() *MonoKSConfigList { + if in == nil { + return nil + } + out := new(MonoKSConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonoKSConfigSpec) DeepCopyInto(out *MonoKSConfigSpec) { + *out = *in + if in.KubeProxyNodePortAddresses != nil { + in, out := &in.KubeProxyNodePortAddresses, &out.KubeProxyNodePortAddresses + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SubjectAltNames != nil { + in, out := &in.SubjectAltNames, &out.SubjectAltNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.NodeLabels != nil { + in, out := &in.NodeLabels, &out.NodeLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Network.DeepCopyInto(&out.Network) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonoKSConfigSpec. +func (in *MonoKSConfigSpec) DeepCopy() *MonoKSConfigSpec { + if in == nil { + return nil + } + out := new(MonoKSConfigSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonoKSConfigStatus) DeepCopyInto(out *MonoKSConfigStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AppliedSteps != nil { + in, out := &in.AppliedSteps, &out.AppliedSteps + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonoKSConfigStatus. +func (in *MonoKSConfigStatus) DeepCopy() *MonoKSConfigStatus { + if in == nil { + return nil + } + out := new(MonoKSConfigStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkSpec) DeepCopyInto(out *NetworkSpec) { + *out = *in + if in.DNSNameservers != nil { + in, out := &in.DNSNameservers, &out.DNSNameservers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.DNSSearchDomains != nil { + in, out := &in.DNSSearchDomains, &out.DNSSearchDomains + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkSpec. +func (in *NetworkSpec) DeepCopy() *NetworkSpec { + if in == nil { + return nil + } + out := new(NetworkSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgrade) DeepCopyInto(out *OSUpgrade) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(OSUpgradeStatus) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgrade. +func (in *OSUpgrade) DeepCopy() *OSUpgrade { + if in == nil { + return nil + } + out := new(OSUpgrade) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OSUpgrade) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeList) DeepCopyInto(out *OSUpgradeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OSUpgrade, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeList. +func (in *OSUpgradeList) DeepCopy() *OSUpgradeList { + if in == nil { + return nil + } + out := new(OSUpgradeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OSUpgradeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeProgress) DeepCopyInto(out *OSUpgradeProgress) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(OSUpgradeProgressStatus) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeProgress. +func (in *OSUpgradeProgress) DeepCopy() *OSUpgradeProgress { + if in == nil { + return nil + } + out := new(OSUpgradeProgress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OSUpgradeProgress) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeProgressList) DeepCopyInto(out *OSUpgradeProgressList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OSUpgradeProgress, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeProgressList. +func (in *OSUpgradeProgressList) DeepCopy() *OSUpgradeProgressList { + if in == nil { + return nil + } + out := new(OSUpgradeProgressList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OSUpgradeProgressList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeProgressSpec) DeepCopyInto(out *OSUpgradeProgressSpec) { + *out = *in + out.SourceRef = in.SourceRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeProgressSpec. +func (in *OSUpgradeProgressSpec) DeepCopy() *OSUpgradeProgressSpec { + if in == nil { + return nil + } + out := new(OSUpgradeProgressSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeProgressStatus) DeepCopyInto(out *OSUpgradeProgressStatus) { + *out = *in + if in.StartedAt != nil { + in, out := &in.StartedAt, &out.StartedAt + *out = (*in).DeepCopy() + } + if in.CompletedAt != nil { + in, out := &in.CompletedAt, &out.CompletedAt + *out = (*in).DeepCopy() + } + if in.LastUpdatedAt != nil { + in, out := &in.LastUpdatedAt, &out.LastUpdatedAt + *out = (*in).DeepCopy() + } + if in.PlannedPath != nil { + in, out := &in.PlannedPath, &out.PlannedPath + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeProgressStatus. +func (in *OSUpgradeProgressStatus) DeepCopy() *OSUpgradeProgressStatus { + if in == nil { + return nil + } + out := new(OSUpgradeProgressStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeSourceRef) DeepCopyInto(out *OSUpgradeSourceRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeSourceRef. +func (in *OSUpgradeSourceRef) DeepCopy() *OSUpgradeSourceRef { + if in == nil { + return nil + } + out := new(OSUpgradeSourceRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeSpec) DeepCopyInto(out *OSUpgradeSpec) { + *out = *in + if in.Catalog != nil { + in, out := &in.Catalog, &out.Catalog + *out = new(VersionCatalogSource) + **out = **in + } + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeSpec. +func (in *OSUpgradeSpec) DeepCopy() *OSUpgradeSpec { + if in == nil { + return nil + } + out := new(OSUpgradeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeStatus) DeepCopyInto(out *OSUpgradeStatus) { + *out = *in + out.Summary = in.Summary + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeStatus. +func (in *OSUpgradeStatus) DeepCopy() *OSUpgradeStatus { + if in == nil { + return nil + } + out := new(OSUpgradeStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSUpgradeSummary) DeepCopyInto(out *OSUpgradeSummary) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSUpgradeSummary. +func (in *OSUpgradeSummary) DeepCopy() *OSUpgradeSummary { + if in == nil { + return nil + } + out := new(OSUpgradeSummary) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VersionCatalogSource) DeepCopyInto(out *VersionCatalogSource) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionCatalogSource. +func (in *VersionCatalogSource) DeepCopy() *VersionCatalogSource { + if in == nil { + return nil + } + out := new(VersionCatalogSource) + in.DeepCopyInto(out) + return out +} diff --git a/clitools/pkg/cmd/agent/agent.go b/clitools/pkg/cmd/agent/agent.go index 47a2f4b..dfc8148 100644 --- a/clitools/pkg/cmd/agent/agent.go +++ b/clitools/pkg/cmd/agent/agent.go @@ -9,10 +9,7 @@ import ( "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/klog/v2" @@ -23,18 +20,13 @@ import ( "example.com/monok8s/pkg/templates" ) -const defaultPollInterval = 15 * time.Second - -var runtimeDefaultUnstructuredConverter = runtime.DefaultUnstructuredConverter - func NewCmdAgent(flags *genericclioptions.ConfigFlags) *cobra.Command { var namespace string var envFile string - var pollInterval time.Duration cmd := &cobra.Command{ Use: "agent --env-file path", - Short: "Watch OSUpgrade resources and process matching upgrades for this node", + Short: "Watch OSUpgradeProgress resources for this node and process upgrades", RunE: func(cmd *cobra.Command, _ []string) error { if envFile == "" { return fmt.Errorf("--env-file is required") @@ -61,7 +53,6 @@ func NewCmdAgent(flags *genericclioptions.ConfigFlags) *cobra.Command { "node", cfg.Spec.NodeName, "namespace", namespace, "envFile", envFile, - "pollInterval", pollInterval, ) clients, err := kube.NewClients(flags) @@ -69,13 +60,12 @@ func NewCmdAgent(flags *genericclioptions.ConfigFlags) *cobra.Command { return fmt.Errorf("create kube clients: %w", err) } - return runPollLoop(ctx, clients, namespace, cfg.Spec.NodeName, pollInterval) + return runWatchLoop(ctx, clients, namespace, cfg.Spec.NodeName) }, } - cmd.Flags().StringVar(&namespace, "namespace", "kube-system", "namespace to watch") + cmd.Flags().StringVar(&namespace, "namespace", templates.DefaultNamespace, "namespace to watch") cmd.Flags().StringVar(&envFile, "env-file", "", "path to env file containing MKS_* variables") - cmd.Flags().DurationVar(&pollInterval, "poll-interval", defaultPollInterval, "poll interval for OSUpgrade resources") return cmd } @@ -94,9 +84,9 @@ func waitForControlGate(ctx context.Context, envFile string, pollInterval time.D for { _, err := os.Stat(marker) if err == nil { - klog.InfoS("Control gate is present; waiting before starting poll loop", "path", marker) + klog.InfoS("Control gate is present; waiting before starting watch loop", "path", marker) } else if os.IsNotExist(err) { - klog.InfoS("Control gate not present; starting poll loop", "path", marker) + klog.InfoS("Control gate not present; starting watch loop", "path", marker) return nil } else { return fmt.Errorf("stat upgrade marker %s: %w", marker, err) @@ -110,126 +100,181 @@ func waitForControlGate(ctx context.Context, envFile string, pollInterval time.D } } -func runPollLoop(ctx context.Context, clients *kube.Clients, namespace, nodeName string, interval time.Duration) error { - gvr := schema.GroupVersionResource{ - Group: monov1alpha1.Group, - Version: monov1alpha1.Version, - Resource: "osupgrades", - } - - ticker := time.NewTicker(interval) - defer ticker.Stop() +func runWatchLoop(ctx context.Context, clients *kube.Clients, namespace, nodeName string) error { + var resourceVersion string for { - if err := pollOnce(ctx, clients, gvr, namespace, nodeName); err != nil { - klog.ErrorS(err, "poll failed", "namespace", namespace, "node", nodeName) + if ctx.Err() != nil { + return ctx.Err() } - select { - case <-ctx.Done(): - return ctx.Err() - case <-ticker.C: + err := watchOnce(ctx, clients, namespace, nodeName, &resourceVersion) + if err != nil { + if ctx.Err() != nil { + return ctx.Err() + } + klog.ErrorS(err, "watch failed; retrying", + "namespace", namespace, + "node", nodeName, + "resourceVersion", resourceVersion, + ) + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(2 * time.Second): + } + continue } } } -func pollOnce( +func watchOnce( ctx context.Context, clients *kube.Clients, - gvr schema.GroupVersionResource, namespace string, nodeName string, + resourceVersion *string, ) error { - list, err := clients.Dynamic.Resource(gvr).Namespace(namespace).List(ctx, metav1.ListOptions{}) + + list, err := clients.MonoKS. + Monok8sV1alpha1(). + OSUpgradeProgresses(namespace). + List(ctx, metav1.ListOptions{}) if err != nil { - return fmt.Errorf("list osupgrades: %w", err) - } - - klog.InfoS("agent tick", "namespace", namespace, "items", len(list.Items), "node", nodeName) - - nodeLabels := labels.Set{ - "kubernetes.io/hostname": nodeName, - "monok8s.io/node-name": nodeName, - "monok8s.io/control-agent": "true", + return fmt.Errorf("list osupgradeprogresses: %w", err) } for i := range list.Items { item := &list.Items[i] - - osu, err := decodeOSUpgrade(item) - if err != nil { - klog.ErrorS(err, "failed to decode osupgrade", - "name", item.GetName(), - "resourceVersion", item.GetResourceVersion(), - ) + if !targetsNode(item, nodeName) { + continue + } + if !shouldHandle(item) { continue } - if !matchesNode(osu, nodeName, nodeLabels) { - klog.V(2).InfoS("skipping osupgrade; not targeted to this node", - "name", osu.Name, - "node", nodeName, - ) - continue - } - - klog.InfoS("matched osupgrade", - "name", osu.Name, + klog.InfoS("found existing osupgradeprogress", + "name", item.Name, "node", nodeName, - "desiredVersion", osu.Spec.DesiredVersion, - "phase", statusPhase(osu.Status), - "resourceVersion", osu.ResourceVersion, + "phase", progressPhase(item.Status), + "resourceVersion", item.ResourceVersion, ) - if err := osupgradeController.HandleOSUpgrade(ctx, clients, namespace, nodeName, osu); err != nil { - klog.ErrorS(err, "failed to handle osupgrade", - "name", osu.Name, + if err := osupgradeController.HandleOSUpgradeProgress(ctx, clients, namespace, nodeName, item); err != nil { + klog.ErrorS(err, "failed to handle existing osupgradeprogress", + "name", item.Name, "node", nodeName, ) - continue } } - return nil -} + *resourceVersion = list.ResourceVersion -func decodeOSUpgrade(item *unstructured.Unstructured) (*monov1alpha1.OSUpgrade, error) { - var osu monov1alpha1.OSUpgrade - if err := runtimeDefaultUnstructuredConverter.FromUnstructured(item.Object, &osu); err != nil { - return nil, fmt.Errorf("convert unstructured to OSUpgrade: %w", err) - } - return &osu, nil -} - -func matchesNode(osu *monov1alpha1.OSUpgrade, nodeName string, nodeLabels labels.Set) bool { - if osu == nil { - return false - } - - sel := osu.Spec.NodeSelector - if sel == nil { - // No selector means "match all nodes". - return true - } - - selector, err := metav1.LabelSelectorAsSelector(sel) + w, err := clients.MonoKS. + Monok8sV1alpha1(). + OSUpgradeProgresses(namespace). + Watch(ctx, metav1.ListOptions{ + ResourceVersion: *resourceVersion, + }) if err != nil { - klog.ErrorS(err, "invalid node selector on osupgrade", "name", osu.Name) + return fmt.Errorf("watch osupgradeprogresses: %w", err) + } + defer w.Stop() + + klog.InfoS("watching osupgradeprogresses", + "namespace", namespace, + "node", nodeName, + "resourceVersion", *resourceVersion, + ) + + for { + select { + case <-ctx.Done(): + return ctx.Err() + + case evt, ok := <-w.ResultChan(): + if !ok { + return fmt.Errorf("watch channel closed") + } + + switch evt.Type { + case watch.Bookmark: + obj, ok := evt.Object.(*monov1alpha1.OSUpgradeProgress) + if ok && obj != nil && obj.ResourceVersion != "" { + *resourceVersion = obj.ResourceVersion + } + continue + + case watch.Error: + return fmt.Errorf("watch returned error event") + } + + osup, ok := evt.Object.(*monov1alpha1.OSUpgradeProgress) + if !ok { + klog.V(1).InfoS("skipping unexpected watch object type", + "type", fmt.Sprintf("%T", evt.Object), + ) + continue + } + + if osup.ResourceVersion != "" { + *resourceVersion = osup.ResourceVersion + } + + if !targetsNode(osup, nodeName) { + continue + } + if !shouldHandle(osup) { + klog.V(2).InfoS("skipping osupgradeprogress due to phase", + "name", osup.Name, + "node", nodeName, + "phase", progressPhase(osup.Status), + "eventType", evt.Type, + ) + continue + } + + klog.InfoS("received osupgradeprogress event", + "name", osup.Name, + "node", nodeName, + "phase", progressPhase(osup.Status), + "eventType", evt.Type, + "resourceVersion", osup.ResourceVersion, + ) + + if err := osupgradeController.HandleOSUpgradeProgress(ctx, clients, namespace, nodeName, osup); err != nil { + klog.ErrorS(err, "failed to handle osupgradeprogress", + "name", osup.Name, + "node", nodeName, + "eventType", evt.Type, + ) + } + } + } +} + +func targetsNode(osup *monov1alpha1.OSUpgradeProgress, nodeName string) bool { + if osup == nil { + return false + } + return osup.Spec.NodeName == nodeName +} + +func shouldHandle(osup *monov1alpha1.OSUpgradeProgress) bool { + if osup == nil { return false } - if selector.Empty() { + switch osup.Status.Phase { + case "", + monov1alpha1.OSUpgradeProgressPhasePending: return true + default: + return false } - - if selector.Matches(nodeLabels) { - return true - } - - return false } -func statusPhase(st *monov1alpha1.OSUpgradeStatus) string { +func progressPhase(st *monov1alpha1.OSUpgradeProgressStatus) string { if st == nil { return "" } diff --git a/clitools/pkg/cmd/controller/controller.go b/clitools/pkg/cmd/controller/controller.go new file mode 100644 index 0000000..88b57d6 --- /dev/null +++ b/clitools/pkg/cmd/controller/controller.go @@ -0,0 +1,97 @@ +package controller + +import ( + "context" + "net" + "net/http" + "os" + "time" + + "github.com/spf13/cobra" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/klog/v2" + + mksadmission "example.com/monok8s/pkg/controller/admission" + "example.com/monok8s/pkg/kube" + "example.com/monok8s/pkg/templates" +) + +type ServerConfig struct { + TLSCertFile string `json:"tlsCertFile,omitempty"` + TLSPrivateKeyFile string `json:"tlsPrivateKeyFile,omitempty"` +} + +func NewCmdController(flags *genericclioptions.ConfigFlags) *cobra.Command { + var namespace string = templates.DefaultNamespace + var conf ServerConfig + + cmd := &cobra.Command{ + Use: "controller", + Short: "Admission controller that handles OSUpgrade resources", + RunE: func(cmd *cobra.Command, _ []string) error { + + ctx := cmd.Context() + + klog.InfoS("starting controller", + "namespace", namespace, + ) + + clients, err := kube.NewClients(flags) + if err != nil { + return err + } + + return httpListen(ctx, clients, conf) + }, + } + + cmd.Flags().StringVar(&namespace, "namespace", templates.DefaultNamespace, "namespace to watch") + cmd.Flags().StringVar(&conf.TLSCertFile, "tls-cert-file", conf.TLSCertFile, + "File containing x509 Certificate used for serving HTTPS (with intermediate certs, if any, concatenated after server cert).") + cmd.Flags().StringVar(&conf.TLSPrivateKeyFile, "tls-private-key-file", conf.TLSPrivateKeyFile, "File containing x509 private key matching --tls-cert-file.") + + return cmd +} + +func httpListen(ctx context.Context, clients *kube.Clients, conf ServerConfig) error { + address, port := "", "8443" + addr := net.JoinHostPort(address, port) + + ns := os.Getenv("POD_NAMESPACE") + nodeName := os.Getenv("NODE_NAME") + + server := mksadmission.NewServer(ctx, clients, ns, nodeName) + + s := &http.Server{ + Addr: addr, + Handler: server, + IdleTimeout: 90 * time.Second, + ReadTimeout: 4 * 60 * time.Minute, + WriteTimeout: 4 * 60 * time.Minute, + MaxHeaderBytes: 1 << 20, + } + + if conf.TLSCertFile != "" { + klog.InfoS("starting HTTPS server", + "addr", addr, + "certFile", conf.TLSCertFile, + "keyFile", conf.TLSPrivateKeyFile, + ) + + if err := s.ListenAndServeTLS(conf.TLSCertFile, conf.TLSPrivateKeyFile); err != nil { + klog.ErrorS(err, "HTTPS server failed") + os.Exit(1) + } + } else { + klog.InfoS("starting HTTP server", + "addr", addr, + ) + + if err := s.ListenAndServe(); err != nil { + klog.ErrorS(err, "HTTP server failed") + os.Exit(1) + } + } + + return nil +} diff --git a/clitools/pkg/cmd/root/root.go b/clitools/pkg/cmd/root/root.go index 30d5c29..2b82b34 100644 --- a/clitools/pkg/cmd/root/root.go +++ b/clitools/pkg/cmd/root/root.go @@ -6,6 +6,7 @@ import ( agentcmd "example.com/monok8s/pkg/cmd/agent" checkconfigcmd "example.com/monok8s/pkg/cmd/checkconfig" + controllercmd "example.com/monok8s/pkg/cmd/controller" createcmd "example.com/monok8s/pkg/cmd/create" initcmd "example.com/monok8s/pkg/cmd/initcmd" internalcmd "example.com/monok8s/pkg/cmd/internal" @@ -45,6 +46,7 @@ func NewRootCmd() *cobra.Command { checkconfigcmd.NewCmdCheckConfig(), createcmd.NewCmdCreate(), agentcmd.NewCmdAgent(flags), + controllercmd.NewCmdController(flags), internalcmd.NewCmdInternal(), ) return cmd diff --git a/clitools/pkg/controller/admission/server.go b/clitools/pkg/controller/admission/server.go new file mode 100644 index 0000000..84ab259 --- /dev/null +++ b/clitools/pkg/controller/admission/server.go @@ -0,0 +1,157 @@ +package admission + +import ( + "context" + "io" + "net/http" + + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + monov1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + "example.com/monok8s/pkg/controller/osupgrade" + "example.com/monok8s/pkg/kube" + + "github.com/emicklei/go-restful/v3" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apiserver/pkg/server/httplog" + "k8s.io/klog/v2" +) + +var ( + scheme = runtime.NewScheme() + codecs = serializer.NewCodecFactory(scheme) + deserializer = codecs.UniversalDeserializer() +) + +var statusesNoTracePred = httplog.StatusIsNot( + http.StatusOK, + http.StatusFound, + http.StatusMovedPermanently, + http.StatusTemporaryRedirect, + http.StatusBadRequest, + http.StatusNotFound, + http.StatusSwitchingProtocols, +) + +func init() { + _ = admissionv1.AddToScheme(scheme) + _ = monov1alpha1.AddToScheme(scheme) +} + +type Server struct { + restfulCont *restful.Container + + ctx context.Context + clients *kube.Clients + namespace string + nodeName string +} + +func NewServer(ctx context.Context, clients *kube.Clients, namespace, nodeName string) *Server { + s := &Server{ + ctx: ctx, + clients: clients, + namespace: namespace, + nodeName: nodeName, + } + s.Initialize() + return s +} + +func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { + if s == nil { + http.Error(w, "admission server is nil", http.StatusInternalServerError) + return + } + if s.restfulCont == nil { + http.Error(w, "admission server not initialized", http.StatusInternalServerError) + return + } + + handler := httplog.WithLogging(s.restfulCont, statusesNoTracePred) + handler.ServeHTTP(w, req) +} + +func (s *Server) Initialize() { + s.restfulCont = restful.NewContainer() + + ws := new(restful.WebService) + + ws.Path("/admission"). + Consumes(restful.MIME_JSON). + Produces(restful.MIME_JSON) + + ws.Route(ws.POST("").To(s.triggerAdmission). + Reads(admissionv1.AdmissionReview{}). + Writes(admissionv1.AdmissionReview{})) + + s.restfulCont.Add(ws) +} + +func (s *Server) triggerAdmission(request *restful.Request, response *restful.Response) { + body, err := io.ReadAll(request.Request.Body) + if err != nil { + _ = response.WriteError(http.StatusBadRequest, err) + return + } + + var reviewReq admissionv1.AdmissionReview + if _, _, err := deserializer.Decode(body, nil, &reviewReq); err != nil { + _ = response.WriteError(http.StatusBadRequest, err) + return + } + if reviewReq.Request == nil { + _ = response.WriteErrorString(http.StatusBadRequest, "missing admission request") + return + } + + resp := admissionv1.AdmissionReview{ + TypeMeta: metav1.TypeMeta{ + Kind: "AdmissionReview", + APIVersion: "admission.k8s.io/v1", + }, + Response: &admissionv1.AdmissionResponse{ + UID: reviewReq.Request.UID, + Allowed: true, + Result: &metav1.Status{Message: "OK"}, + }, + } + + var osu monov1alpha1.OSUpgrade + if _, _, err := deserializer.Decode(reviewReq.Request.Object.Raw, nil, &osu); err != nil { + klog.V(1).InfoS("Skipping non-OSUpgrade resource", + "uid", reviewReq.Request.UID, + "kind", reviewReq.Request.Kind.Kind, + "operation", reviewReq.Request.Operation, + "err", err, + ) + _ = response.WriteEntity(resp) + return + } + + klog.InfoS("Received OSUpgrade admission", + "uid", reviewReq.Request.UID, + "operation", reviewReq.Request.Operation, + "name", osu.Name, + "namespace", osu.Namespace, + "node", s.nodeName, + ) + + // Resolve every node name + if err := osupgrade.EnsureOSUpgradeProgressForNode( + s.ctx, + s.clients, + s.namespace, + s.nodeName, + &osu, + ); err != nil { + klog.ErrorS(err, "ensure OSUpgradeProgress for node failed", + "osupgrade", osu.Name, + "node", s.nodeName, + ) + } + + _ = response.WriteEntity(resp) +} diff --git a/clitools/pkg/controller/osupgrade/handler.go b/clitools/pkg/controller/osupgrade/handler.go index 4bd6e24..af60af6 100644 --- a/clitools/pkg/controller/osupgrade/handler.go +++ b/clitools/pkg/controller/osupgrade/handler.go @@ -41,26 +41,55 @@ func (r *UpgradeRunner) Run(fn func() error) error { return fn() } -func HandleOSUpgrade(ctx context.Context, clients *kube.Clients, - namespace string, nodeName string, - osu *monov1alpha1.OSUpgrade, +func HandleOSUpgradeProgress( + ctx context.Context, + clients *kube.Clients, + namespace string, + nodeName string, + osup *monov1alpha1.OSUpgradeProgress, ) error { return r.Run(func() error { - return handleOSUpgradeLocked(ctx, clients, namespace, nodeName, osu) + return handleOSUpgradeProgressLocked(ctx, clients, namespace, nodeName, osup) }) } -func handleOSUpgradeLocked(ctx context.Context, clients *kube.Clients, - namespace string, nodeName string, - osu *monov1alpha1.OSUpgrade, +func handleOSUpgradeProgressLocked( + ctx context.Context, + clients *kube.Clients, + namespace string, + nodeName string, + osup *monov1alpha1.OSUpgradeProgress, ) error { - osup, err := ensureProgressHeartbeat(ctx, clients, namespace, nodeName, osu) - if err != nil { - return err + if osup == nil { + return fmt.Errorf("osupgradeprogress is nil") } - klog.InfoS("handling osupgrade", - "name", osu.Name, + if osup.Spec.NodeName != nodeName { + return nil + } + + if osup.Status.Phase != "" && + osup.Status.Phase != monov1alpha1.OSUpgradeProgressPhasePending && + osup.Status.Phase != monov1alpha1.OSUpgradeProgressPhaseDownloading { + // tune this logic however you want + return nil + } + + parentName := osup.Spec.SourceRef.Name + if parentName == "" { + return failProgress(ctx, clients, osup, "resolve parent osupgrade", fmt.Errorf("missing spec.osUpgradeName")) + } + + osu, err := clients.MonoKS.Monok8sV1alpha1(). + OSUpgrades(namespace). + Get(ctx, parentName, metav1.GetOptions{}) + if err != nil { + return failProgress(ctx, clients, osup, "resolve parent osupgrade", err) + } + + klog.InfoS("handling osupgradeprogress", + "name", osup.Name, + "osupgrade", osu.Name, "node", nodeName, "desiredVersion", osu.Spec.DesiredVersion, ) diff --git a/clitools/pkg/controller/osupgrade/progress.go b/clitools/pkg/controller/osupgrade/progress.go index 40771fe..c537b6c 100644 --- a/clitools/pkg/controller/osupgrade/progress.go +++ b/clitools/pkg/controller/osupgrade/progress.go @@ -28,6 +28,33 @@ var ( } ) +func EnsureOSUpgradeProgressForNode( + ctx context.Context, + clients *kube.Clients, + namespace string, + nodeName string, + osu *monov1alpha1.OSUpgrade, +) error { + if osu == nil { + return fmt.Errorf("osupgrade is nil") + } + + // Keep using your existing helper if it already encapsulates + // selector matching / parent linkage / create-or-update semantics. + osup, err := ensureProgressHeartbeat(ctx, clients, namespace, nodeName, osu) + if err != nil { + return err + } + + klog.InfoS("ensured OSUpgradeProgress from admission", + "osupgrade", osu.Name, + "osupgradeProgress", osup.Name, + "node", nodeName, + ) + + return nil +} + func ensureProgressHeartbeat(ctx context.Context, clients *kube.Clients, namespace string, nodeName string, osu *monov1alpha1.OSUpgrade, diff --git a/clitools/pkg/generated/clientset/versioned/clientset.go b/clitools/pkg/generated/clientset/versioned/clientset.go new file mode 100644 index 0000000..06bd6bd --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/clientset.go @@ -0,0 +1,106 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package versioned + +import ( + fmt "fmt" + http "net/http" + + monok8sv1alpha1 "example.com/monok8s/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1" + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + Monok8sV1alpha1() monok8sv1alpha1.Monok8sV1alpha1Interface +} + +// Clientset contains the clients for groups. +type Clientset struct { + *discovery.DiscoveryClient + monok8sV1alpha1 *monok8sv1alpha1.Monok8sV1alpha1Client +} + +// Monok8sV1alpha1 retrieves the Monok8sV1alpha1Client +func (c *Clientset) Monok8sV1alpha1() monok8sv1alpha1.Monok8sV1alpha1Interface { + return c.monok8sV1alpha1 +} + +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + +// NewForConfig creates a new Clientset for the given config. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfig will generate a rate-limiter in configShallowCopy. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + + if configShallowCopy.UserAgent == "" { + configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent() + } + + // share the transport between all clients + httpClient, err := rest.HTTPClientFor(&configShallowCopy) + if err != nil { + return nil, err + } + + return NewForConfigAndClient(&configShallowCopy, httpClient) +} + +// NewForConfigAndClient creates a new Clientset for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfigAndClient will generate a rate-limiter in configShallowCopy. +func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + if configShallowCopy.Burst <= 0 { + return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") + } + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + + var cs Clientset + var err error + cs.monok8sV1alpha1, err = monok8sv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + return &cs, nil +} + +// NewForConfigOrDie creates a new Clientset for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Clientset { + cs, err := NewForConfig(c) + if err != nil { + panic(err) + } + return cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.monok8sV1alpha1 = monok8sv1alpha1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/clitools/pkg/generated/clientset/versioned/fake/clientset_generated.go b/clitools/pkg/generated/clientset/versioned/fake/clientset_generated.go new file mode 100644 index 0000000..3d05999 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -0,0 +1,91 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + clientset "example.com/monok8s/pkg/generated/clientset/versioned" + monok8sv1alpha1 "example.com/monok8s/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1" + fakemonok8sv1alpha1 "example.com/monok8s/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/testing" +) + +// NewSimpleClientset returns a clientset that will respond with the provided objects. +// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, +// without applying any field management, validations and/or defaults. It shouldn't be considered a replacement +// for a real clientset and is mostly useful in simple unit tests. +// +// Deprecated: NewClientset replaces this with support for field management, which significantly improves +// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. +// via --with-applyconfig). +func NewSimpleClientset(objects ...runtime.Object) *Clientset { + o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) + for _, obj := range objects { + if err := o.Add(obj); err != nil { + panic(err) + } + } + + cs := &Clientset{tracker: o} + cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} + cs.AddReactor("*", "*", testing.ObjectReaction(o)) + cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { + var opts metav1.ListOptions + if watchAction, ok := action.(testing.WatchActionImpl); ok { + opts = watchAction.ListOptions + } + gvr := action.GetResource() + ns := action.GetNamespace() + watch, err := o.Watch(gvr, ns, opts) + if err != nil { + return false, nil, err + } + return true, watch, nil + }) + + return cs +} + +// Clientset implements clientset.Interface. Meant to be embedded into a +// struct to get a default implementation. This makes faking out just the method +// you want to test easier. +type Clientset struct { + testing.Fake + discovery *fakediscovery.FakeDiscovery + tracker testing.ObjectTracker +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +func (c *Clientset) Tracker() testing.ObjectTracker { + return c.tracker +} + +// IsWatchListSemanticsSupported informs the reflector that this client +// doesn't support WatchList semantics. +// +// This is a synthetic method whose sole purpose is to satisfy the optional +// interface check performed by the reflector. +// Returning true signals that WatchList can NOT be used. +// No additional logic is implemented here. +func (c *Clientset) IsWatchListSemanticsUnSupported() bool { + return true +} + +var ( + _ clientset.Interface = &Clientset{} + _ testing.FakeClient = &Clientset{} +) + +// Monok8sV1alpha1 retrieves the Monok8sV1alpha1Client +func (c *Clientset) Monok8sV1alpha1() monok8sv1alpha1.Monok8sV1alpha1Interface { + return &fakemonok8sv1alpha1.FakeMonok8sV1alpha1{Fake: &c.Fake} +} diff --git a/clitools/pkg/generated/clientset/versioned/fake/doc.go b/clitools/pkg/generated/clientset/versioned/fake/doc.go new file mode 100644 index 0000000..ff3a27c --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/fake/doc.go @@ -0,0 +1,6 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/clitools/pkg/generated/clientset/versioned/fake/register.go b/clitools/pkg/generated/clientset/versioned/fake/register.go new file mode 100644 index 0000000..75b5b4f --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/fake/register.go @@ -0,0 +1,42 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + monok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var scheme = runtime.NewScheme() +var codecs = serializer.NewCodecFactory(scheme) + +var localSchemeBuilder = runtime.SchemeBuilder{ + monok8sv1alpha1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) +} diff --git a/clitools/pkg/generated/clientset/versioned/scheme/doc.go b/clitools/pkg/generated/clientset/versioned/scheme/doc.go new file mode 100644 index 0000000..7834d39 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/scheme/doc.go @@ -0,0 +1,6 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/clitools/pkg/generated/clientset/versioned/scheme/register.go b/clitools/pkg/generated/clientset/versioned/scheme/register.go new file mode 100644 index 0000000..c342a9c --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/scheme/register.go @@ -0,0 +1,42 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + monok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + monok8sv1alpha1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/doc.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/doc.go new file mode 100644 index 0000000..d089847 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/doc.go @@ -0,0 +1,6 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/doc.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/doc.go new file mode 100644 index 0000000..0edf26f --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/doc.go @@ -0,0 +1,6 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_monok8s_client.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_monok8s_client.go new file mode 100644 index 0000000..24ce525 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_monok8s_client.go @@ -0,0 +1,30 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "example.com/monok8s/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeMonok8sV1alpha1 struct { + *testing.Fake +} + +func (c *FakeMonok8sV1alpha1) OSUpgrades(namespace string) v1alpha1.OSUpgradeInterface { + return newFakeOSUpgrades(c, namespace) +} + +func (c *FakeMonok8sV1alpha1) OSUpgradeProgresses(namespace string) v1alpha1.OSUpgradeProgressInterface { + return newFakeOSUpgradeProgresses(c, namespace) +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeMonok8sV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgrade.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgrade.go new file mode 100644 index 0000000..7ee1874 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgrade.go @@ -0,0 +1,36 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + monok8sv1alpha1 "example.com/monok8s/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1" + gentype "k8s.io/client-go/gentype" +) + +// fakeOSUpgrades implements OSUpgradeInterface +type fakeOSUpgrades struct { + *gentype.FakeClientWithList[*v1alpha1.OSUpgrade, *v1alpha1.OSUpgradeList] + Fake *FakeMonok8sV1alpha1 +} + +func newFakeOSUpgrades(fake *FakeMonok8sV1alpha1, namespace string) monok8sv1alpha1.OSUpgradeInterface { + return &fakeOSUpgrades{ + gentype.NewFakeClientWithList[*v1alpha1.OSUpgrade, *v1alpha1.OSUpgradeList]( + fake.Fake, + namespace, + v1alpha1.SchemeGroupVersion.WithResource("osupgrades"), + v1alpha1.SchemeGroupVersion.WithKind("OSUpgrade"), + func() *v1alpha1.OSUpgrade { return &v1alpha1.OSUpgrade{} }, + func() *v1alpha1.OSUpgradeList { return &v1alpha1.OSUpgradeList{} }, + func(dst, src *v1alpha1.OSUpgradeList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.OSUpgradeList) []*v1alpha1.OSUpgrade { return gentype.ToPointerSlice(list.Items) }, + func(list *v1alpha1.OSUpgradeList, items []*v1alpha1.OSUpgrade) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgradeprogress.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgradeprogress.go new file mode 100644 index 0000000..d0fa7f1 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/fake/fake_osupgradeprogress.go @@ -0,0 +1,38 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + monok8sv1alpha1 "example.com/monok8s/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1" + gentype "k8s.io/client-go/gentype" +) + +// fakeOSUpgradeProgresses implements OSUpgradeProgressInterface +type fakeOSUpgradeProgresses struct { + *gentype.FakeClientWithList[*v1alpha1.OSUpgradeProgress, *v1alpha1.OSUpgradeProgressList] + Fake *FakeMonok8sV1alpha1 +} + +func newFakeOSUpgradeProgresses(fake *FakeMonok8sV1alpha1, namespace string) monok8sv1alpha1.OSUpgradeProgressInterface { + return &fakeOSUpgradeProgresses{ + gentype.NewFakeClientWithList[*v1alpha1.OSUpgradeProgress, *v1alpha1.OSUpgradeProgressList]( + fake.Fake, + namespace, + v1alpha1.SchemeGroupVersion.WithResource("osupgradeprogresses"), + v1alpha1.SchemeGroupVersion.WithKind("OSUpgradeProgress"), + func() *v1alpha1.OSUpgradeProgress { return &v1alpha1.OSUpgradeProgress{} }, + func() *v1alpha1.OSUpgradeProgressList { return &v1alpha1.OSUpgradeProgressList{} }, + func(dst, src *v1alpha1.OSUpgradeProgressList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.OSUpgradeProgressList) []*v1alpha1.OSUpgradeProgress { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1alpha1.OSUpgradeProgressList, items []*v1alpha1.OSUpgradeProgress) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/generated_expansion.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/generated_expansion.go new file mode 100644 index 0000000..5b936f5 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/generated_expansion.go @@ -0,0 +1,9 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type OSUpgradeExpansion interface{} + +type OSUpgradeProgressExpansion interface{} diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/monok8s_client.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/monok8s_client.go new file mode 100644 index 0000000..7c3a7a7 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/monok8s_client.go @@ -0,0 +1,92 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + http "net/http" + + monok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + scheme "example.com/monok8s/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type Monok8sV1alpha1Interface interface { + RESTClient() rest.Interface + OSUpgradesGetter + OSUpgradeProgressesGetter +} + +// Monok8sV1alpha1Client is used to interact with features provided by the monok8s group. +type Monok8sV1alpha1Client struct { + restClient rest.Interface +} + +func (c *Monok8sV1alpha1Client) OSUpgrades(namespace string) OSUpgradeInterface { + return newOSUpgrades(c, namespace) +} + +func (c *Monok8sV1alpha1Client) OSUpgradeProgresses(namespace string) OSUpgradeProgressInterface { + return newOSUpgradeProgresses(c, namespace) +} + +// NewForConfig creates a new Monok8sV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*Monok8sV1alpha1Client, error) { + config := *c + setConfigDefaults(&config) + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new Monok8sV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*Monok8sV1alpha1Client, error) { + config := *c + setConfigDefaults(&config) + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &Monok8sV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new Monok8sV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Monok8sV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new Monok8sV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *Monok8sV1alpha1Client { + return &Monok8sV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) { + gv := monok8sv1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *Monok8sV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgrade.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgrade.go new file mode 100644 index 0000000..a0f3cb6 --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgrade.go @@ -0,0 +1,56 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + + monok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + scheme "example.com/monok8s/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// OSUpgradesGetter has a method to return a OSUpgradeInterface. +// A group's client should implement this interface. +type OSUpgradesGetter interface { + OSUpgrades(namespace string) OSUpgradeInterface +} + +// OSUpgradeInterface has methods to work with OSUpgrade resources. +type OSUpgradeInterface interface { + Create(ctx context.Context, oSUpgrade *monok8sv1alpha1.OSUpgrade, opts v1.CreateOptions) (*monok8sv1alpha1.OSUpgrade, error) + Update(ctx context.Context, oSUpgrade *monok8sv1alpha1.OSUpgrade, opts v1.UpdateOptions) (*monok8sv1alpha1.OSUpgrade, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, oSUpgrade *monok8sv1alpha1.OSUpgrade, opts v1.UpdateOptions) (*monok8sv1alpha1.OSUpgrade, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*monok8sv1alpha1.OSUpgrade, error) + List(ctx context.Context, opts v1.ListOptions) (*monok8sv1alpha1.OSUpgradeList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *monok8sv1alpha1.OSUpgrade, err error) + OSUpgradeExpansion +} + +// oSUpgrades implements OSUpgradeInterface +type oSUpgrades struct { + *gentype.ClientWithList[*monok8sv1alpha1.OSUpgrade, *monok8sv1alpha1.OSUpgradeList] +} + +// newOSUpgrades returns a OSUpgrades +func newOSUpgrades(c *Monok8sV1alpha1Client, namespace string) *oSUpgrades { + return &oSUpgrades{ + gentype.NewClientWithList[*monok8sv1alpha1.OSUpgrade, *monok8sv1alpha1.OSUpgradeList]( + "osupgrades", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *monok8sv1alpha1.OSUpgrade { return &monok8sv1alpha1.OSUpgrade{} }, + func() *monok8sv1alpha1.OSUpgradeList { return &monok8sv1alpha1.OSUpgradeList{} }, + ), + } +} diff --git a/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgradeprogress.go b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgradeprogress.go new file mode 100644 index 0000000..8526e6f --- /dev/null +++ b/clitools/pkg/generated/clientset/versioned/typed/monok8s/v1alpha1/osupgradeprogress.go @@ -0,0 +1,56 @@ +/* MIT License */ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + + monok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + scheme "example.com/monok8s/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// OSUpgradeProgressesGetter has a method to return a OSUpgradeProgressInterface. +// A group's client should implement this interface. +type OSUpgradeProgressesGetter interface { + OSUpgradeProgresses(namespace string) OSUpgradeProgressInterface +} + +// OSUpgradeProgressInterface has methods to work with OSUpgradeProgress resources. +type OSUpgradeProgressInterface interface { + Create(ctx context.Context, oSUpgradeProgress *monok8sv1alpha1.OSUpgradeProgress, opts v1.CreateOptions) (*monok8sv1alpha1.OSUpgradeProgress, error) + Update(ctx context.Context, oSUpgradeProgress *monok8sv1alpha1.OSUpgradeProgress, opts v1.UpdateOptions) (*monok8sv1alpha1.OSUpgradeProgress, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, oSUpgradeProgress *monok8sv1alpha1.OSUpgradeProgress, opts v1.UpdateOptions) (*monok8sv1alpha1.OSUpgradeProgress, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*monok8sv1alpha1.OSUpgradeProgress, error) + List(ctx context.Context, opts v1.ListOptions) (*monok8sv1alpha1.OSUpgradeProgressList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *monok8sv1alpha1.OSUpgradeProgress, err error) + OSUpgradeProgressExpansion +} + +// oSUpgradeProgresses implements OSUpgradeProgressInterface +type oSUpgradeProgresses struct { + *gentype.ClientWithList[*monok8sv1alpha1.OSUpgradeProgress, *monok8sv1alpha1.OSUpgradeProgressList] +} + +// newOSUpgradeProgresses returns a OSUpgradeProgresses +func newOSUpgradeProgresses(c *Monok8sV1alpha1Client, namespace string) *oSUpgradeProgresses { + return &oSUpgradeProgresses{ + gentype.NewClientWithList[*monok8sv1alpha1.OSUpgradeProgress, *monok8sv1alpha1.OSUpgradeProgressList]( + "osupgradeprogresses", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *monok8sv1alpha1.OSUpgradeProgress { return &monok8sv1alpha1.OSUpgradeProgress{} }, + func() *monok8sv1alpha1.OSUpgradeProgressList { return &monok8sv1alpha1.OSUpgradeProgressList{} }, + ), + } +} diff --git a/clitools/pkg/generated/informers/externalversions/factory.go b/clitools/pkg/generated/informers/externalversions/factory.go new file mode 100644 index 0000000..55210f7 --- /dev/null +++ b/clitools/pkg/generated/informers/externalversions/factory.go @@ -0,0 +1,249 @@ +/* MIT License */ + +// Code generated by informer-gen. DO NOT EDIT. + +package externalversions + +import ( + reflect "reflect" + sync "sync" + time "time" + + versioned "example.com/monok8s/pkg/generated/clientset/versioned" + internalinterfaces "example.com/monok8s/pkg/generated/informers/externalversions/internalinterfaces" + monok8s "example.com/monok8s/pkg/generated/informers/externalversions/monok8s" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + cache "k8s.io/client-go/tools/cache" +) + +// SharedInformerOption defines the functional option type for SharedInformerFactory. +type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory + +type sharedInformerFactory struct { + client versioned.Interface + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc + lock sync.Mutex + defaultResync time.Duration + customResync map[reflect.Type]time.Duration + transform cache.TransformFunc + + informers map[reflect.Type]cache.SharedIndexInformer + // startedInformers is used for tracking which informers have been started. + // This allows Start() to be called multiple times safely. + startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool +} + +// WithCustomResyncConfig sets a custom resync period for the specified informer types. +func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + for k, v := range resyncConfig { + factory.customResync[reflect.TypeOf(k)] = v + } + return factory + } +} + +// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. +func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.tweakListOptions = tweakListOptions + return factory + } +} + +// WithNamespace limits the SharedInformerFactory to the specified namespace. +func WithNamespace(namespace string) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.namespace = namespace + return factory + } +} + +// WithTransform sets a transform on all informers. +func WithTransform(transform cache.TransformFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.transform = transform + return factory + } +} + +// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. +func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync) +} + +// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. +// Listers obtained via this SharedInformerFactory will be subject to the same filters +// as specified here. +// +// Deprecated: Please use NewSharedInformerFactoryWithOptions instead +func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) +} + +// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. +func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { + factory := &sharedInformerFactory{ + client: client, + namespace: v1.NamespaceAll, + defaultResync: defaultResync, + informers: make(map[reflect.Type]cache.SharedIndexInformer), + startedInformers: make(map[reflect.Type]bool), + customResync: make(map[reflect.Type]time.Duration), + } + + // Apply all options + for _, opt := range options { + factory = opt(factory) + } + + return factory +} + +func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.shuttingDown { + return + } + + for informerType, informer := range f.informers { + if !f.startedInformers[informerType] { + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() + f.startedInformers[informerType] = true + } + } +} + +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + +func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + informers := func() map[reflect.Type]cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[reflect.Type]cache.SharedIndexInformer{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer + } + } + return informers + }() + + res := map[reflect.Type]bool{} + for informType, informer := range informers { + res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + } + return res +} + +// InformerFor returns the SharedIndexInformer for obj using an internal +// client. +func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informerType := reflect.TypeOf(obj) + informer, exists := f.informers[informerType] + if exists { + return informer + } + + resyncPeriod, exists := f.customResync[informerType] + if !exists { + resyncPeriod = f.defaultResync + } + + informer = newFunc(f.client, resyncPeriod) + informer.SetTransform(f.transform) + f.informers[informerType] = informer + + return informer +} + +// SharedInformerFactory provides shared informers for resources in all known +// API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.WithCancel(context.Background()) +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) +type SharedInformerFactory interface { + internalinterfaces.SharedInformerFactory + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. + WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + + Monok8s() monok8s.Interface +} + +func (f *sharedInformerFactory) Monok8s() monok8s.Interface { + return monok8s.New(f, f.namespace, f.tweakListOptions) +} diff --git a/clitools/pkg/generated/informers/externalversions/generic.go b/clitools/pkg/generated/informers/externalversions/generic.go new file mode 100644 index 0000000..d3b53a5 --- /dev/null +++ b/clitools/pkg/generated/informers/externalversions/generic.go @@ -0,0 +1,50 @@ +/* MIT License */ + +// Code generated by informer-gen. DO NOT EDIT. + +package externalversions + +import ( + fmt "fmt" + + v1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + schema "k8s.io/apimachinery/pkg/runtime/schema" + cache "k8s.io/client-go/tools/cache" +) + +// GenericInformer is type of SharedIndexInformer which will locate and delegate to other +// sharedInformers based on type +type GenericInformer interface { + Informer() cache.SharedIndexInformer + Lister() cache.GenericLister +} + +type genericInformer struct { + informer cache.SharedIndexInformer + resource schema.GroupResource +} + +// Informer returns the SharedIndexInformer. +func (f *genericInformer) Informer() cache.SharedIndexInformer { + return f.informer +} + +// Lister returns the GenericLister. +func (f *genericInformer) Lister() cache.GenericLister { + return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) +} + +// ForResource gives generic access to a shared informer of the matching type +// TODO extend this to unknown resources with a client pool +func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { + switch resource { + // Group=monok8s, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("osupgrades"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Monok8s().V1alpha1().OSUpgrades().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("osupgradeprogresses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Monok8s().V1alpha1().OSUpgradeProgresses().Informer()}, nil + + } + + return nil, fmt.Errorf("no informer found for %v", resource) +} diff --git a/clitools/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go b/clitools/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go new file mode 100644 index 0000000..c963afb --- /dev/null +++ b/clitools/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -0,0 +1,26 @@ +/* MIT License */ + +// Code generated by informer-gen. DO NOT EDIT. + +package internalinterfaces + +import ( + time "time" + + versioned "example.com/monok8s/pkg/generated/clientset/versioned" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + cache "k8s.io/client-go/tools/cache" +) + +// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. +type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer + +// SharedInformerFactory a small interface to allow for adding an informer without an import cycle +type SharedInformerFactory interface { + Start(stopCh <-chan struct{}) + InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer +} + +// TweakListOptionsFunc is a function that transforms a v1.ListOptions. +type TweakListOptionsFunc func(*v1.ListOptions) diff --git a/clitools/pkg/generated/informers/externalversions/monok8s/interface.go b/clitools/pkg/generated/informers/externalversions/monok8s/interface.go new file mode 100644 index 0000000..9e39f5d --- /dev/null +++ b/clitools/pkg/generated/informers/externalversions/monok8s/interface.go @@ -0,0 +1,32 @@ +/* MIT License */ + +// Code generated by informer-gen. DO NOT EDIT. + +package monok8s + +import ( + internalinterfaces "example.com/monok8s/pkg/generated/informers/externalversions/internalinterfaces" + v1alpha1 "example.com/monok8s/pkg/generated/informers/externalversions/monok8s/v1alpha1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/interface.go b/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/interface.go new file mode 100644 index 0000000..4cb8d11 --- /dev/null +++ b/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/interface.go @@ -0,0 +1,38 @@ +/* MIT License */ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "example.com/monok8s/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // OSUpgrades returns a OSUpgradeInformer. + OSUpgrades() OSUpgradeInformer + // OSUpgradeProgresses returns a OSUpgradeProgressInformer. + OSUpgradeProgresses() OSUpgradeProgressInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// OSUpgrades returns a OSUpgradeInformer. +func (v *version) OSUpgrades() OSUpgradeInformer { + return &oSUpgradeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// OSUpgradeProgresses returns a OSUpgradeProgressInformer. +func (v *version) OSUpgradeProgresses() OSUpgradeProgressInformer { + return &oSUpgradeProgressInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgrade.go b/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgrade.go new file mode 100644 index 0000000..036b00a --- /dev/null +++ b/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgrade.go @@ -0,0 +1,88 @@ +/* MIT License */ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + time "time" + + apismonok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + versioned "example.com/monok8s/pkg/generated/clientset/versioned" + internalinterfaces "example.com/monok8s/pkg/generated/informers/externalversions/internalinterfaces" + monok8sv1alpha1 "example.com/monok8s/pkg/generated/listers/monok8s/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// OSUpgradeInformer provides access to a shared informer and lister for +// OSUpgrades. +type OSUpgradeInformer interface { + Informer() cache.SharedIndexInformer + Lister() monok8sv1alpha1.OSUpgradeLister +} + +type oSUpgradeInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewOSUpgradeInformer constructs a new informer for OSUpgrade type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOSUpgradeInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredOSUpgradeInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredOSUpgradeInformer constructs a new informer for OSUpgrade type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredOSUpgradeInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgrades(namespace).List(context.Background(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgrades(namespace).Watch(context.Background(), options) + }, + ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgrades(namespace).List(ctx, options) + }, + WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgrades(namespace).Watch(ctx, options) + }, + }, client), + &apismonok8sv1alpha1.OSUpgrade{}, + resyncPeriod, + indexers, + ) +} + +func (f *oSUpgradeInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredOSUpgradeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *oSUpgradeInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apismonok8sv1alpha1.OSUpgrade{}, f.defaultInformer) +} + +func (f *oSUpgradeInformer) Lister() monok8sv1alpha1.OSUpgradeLister { + return monok8sv1alpha1.NewOSUpgradeLister(f.Informer().GetIndexer()) +} diff --git a/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgradeprogress.go b/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgradeprogress.go new file mode 100644 index 0000000..5995e3e --- /dev/null +++ b/clitools/pkg/generated/informers/externalversions/monok8s/v1alpha1/osupgradeprogress.go @@ -0,0 +1,88 @@ +/* MIT License */ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + time "time" + + apismonok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + versioned "example.com/monok8s/pkg/generated/clientset/versioned" + internalinterfaces "example.com/monok8s/pkg/generated/informers/externalversions/internalinterfaces" + monok8sv1alpha1 "example.com/monok8s/pkg/generated/listers/monok8s/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// OSUpgradeProgressInformer provides access to a shared informer and lister for +// OSUpgradeProgresses. +type OSUpgradeProgressInformer interface { + Informer() cache.SharedIndexInformer + Lister() monok8sv1alpha1.OSUpgradeProgressLister +} + +type oSUpgradeProgressInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewOSUpgradeProgressInformer constructs a new informer for OSUpgradeProgress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOSUpgradeProgressInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredOSUpgradeProgressInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredOSUpgradeProgressInformer constructs a new informer for OSUpgradeProgress type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredOSUpgradeProgressInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgradeProgresses(namespace).List(context.Background(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgradeProgresses(namespace).Watch(context.Background(), options) + }, + ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgradeProgresses(namespace).List(ctx, options) + }, + WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Monok8sV1alpha1().OSUpgradeProgresses(namespace).Watch(ctx, options) + }, + }, client), + &apismonok8sv1alpha1.OSUpgradeProgress{}, + resyncPeriod, + indexers, + ) +} + +func (f *oSUpgradeProgressInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredOSUpgradeProgressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *oSUpgradeProgressInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apismonok8sv1alpha1.OSUpgradeProgress{}, f.defaultInformer) +} + +func (f *oSUpgradeProgressInformer) Lister() monok8sv1alpha1.OSUpgradeProgressLister { + return monok8sv1alpha1.NewOSUpgradeProgressLister(f.Informer().GetIndexer()) +} diff --git a/clitools/pkg/generated/listers/monok8s/v1alpha1/expansion_generated.go b/clitools/pkg/generated/listers/monok8s/v1alpha1/expansion_generated.go new file mode 100644 index 0000000..8579589 --- /dev/null +++ b/clitools/pkg/generated/listers/monok8s/v1alpha1/expansion_generated.go @@ -0,0 +1,21 @@ +/* MIT License */ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// OSUpgradeListerExpansion allows custom methods to be added to +// OSUpgradeLister. +type OSUpgradeListerExpansion interface{} + +// OSUpgradeNamespaceListerExpansion allows custom methods to be added to +// OSUpgradeNamespaceLister. +type OSUpgradeNamespaceListerExpansion interface{} + +// OSUpgradeProgressListerExpansion allows custom methods to be added to +// OSUpgradeProgressLister. +type OSUpgradeProgressListerExpansion interface{} + +// OSUpgradeProgressNamespaceListerExpansion allows custom methods to be added to +// OSUpgradeProgressNamespaceLister. +type OSUpgradeProgressNamespaceListerExpansion interface{} diff --git a/clitools/pkg/generated/listers/monok8s/v1alpha1/osupgrade.go b/clitools/pkg/generated/listers/monok8s/v1alpha1/osupgrade.go new file mode 100644 index 0000000..0271250 --- /dev/null +++ b/clitools/pkg/generated/listers/monok8s/v1alpha1/osupgrade.go @@ -0,0 +1,56 @@ +/* MIT License */ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + monok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// OSUpgradeLister helps list OSUpgrades. +// All objects returned here must be treated as read-only. +type OSUpgradeLister interface { + // List lists all OSUpgrades in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*monok8sv1alpha1.OSUpgrade, err error) + // OSUpgrades returns an object that can list and get OSUpgrades. + OSUpgrades(namespace string) OSUpgradeNamespaceLister + OSUpgradeListerExpansion +} + +// oSUpgradeLister implements the OSUpgradeLister interface. +type oSUpgradeLister struct { + listers.ResourceIndexer[*monok8sv1alpha1.OSUpgrade] +} + +// NewOSUpgradeLister returns a new OSUpgradeLister. +func NewOSUpgradeLister(indexer cache.Indexer) OSUpgradeLister { + return &oSUpgradeLister{listers.New[*monok8sv1alpha1.OSUpgrade](indexer, monok8sv1alpha1.Resource("osupgrade"))} +} + +// OSUpgrades returns an object that can list and get OSUpgrades. +func (s *oSUpgradeLister) OSUpgrades(namespace string) OSUpgradeNamespaceLister { + return oSUpgradeNamespaceLister{listers.NewNamespaced[*monok8sv1alpha1.OSUpgrade](s.ResourceIndexer, namespace)} +} + +// OSUpgradeNamespaceLister helps list and get OSUpgrades. +// All objects returned here must be treated as read-only. +type OSUpgradeNamespaceLister interface { + // List lists all OSUpgrades in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*monok8sv1alpha1.OSUpgrade, err error) + // Get retrieves the OSUpgrade from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*monok8sv1alpha1.OSUpgrade, error) + OSUpgradeNamespaceListerExpansion +} + +// oSUpgradeNamespaceLister implements the OSUpgradeNamespaceLister +// interface. +type oSUpgradeNamespaceLister struct { + listers.ResourceIndexer[*monok8sv1alpha1.OSUpgrade] +} diff --git a/clitools/pkg/generated/listers/monok8s/v1alpha1/osupgradeprogress.go b/clitools/pkg/generated/listers/monok8s/v1alpha1/osupgradeprogress.go new file mode 100644 index 0000000..5e60e2d --- /dev/null +++ b/clitools/pkg/generated/listers/monok8s/v1alpha1/osupgradeprogress.go @@ -0,0 +1,56 @@ +/* MIT License */ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + monok8sv1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// OSUpgradeProgressLister helps list OSUpgradeProgresses. +// All objects returned here must be treated as read-only. +type OSUpgradeProgressLister interface { + // List lists all OSUpgradeProgresses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*monok8sv1alpha1.OSUpgradeProgress, err error) + // OSUpgradeProgresses returns an object that can list and get OSUpgradeProgresses. + OSUpgradeProgresses(namespace string) OSUpgradeProgressNamespaceLister + OSUpgradeProgressListerExpansion +} + +// oSUpgradeProgressLister implements the OSUpgradeProgressLister interface. +type oSUpgradeProgressLister struct { + listers.ResourceIndexer[*monok8sv1alpha1.OSUpgradeProgress] +} + +// NewOSUpgradeProgressLister returns a new OSUpgradeProgressLister. +func NewOSUpgradeProgressLister(indexer cache.Indexer) OSUpgradeProgressLister { + return &oSUpgradeProgressLister{listers.New[*monok8sv1alpha1.OSUpgradeProgress](indexer, monok8sv1alpha1.Resource("osupgradeprogress"))} +} + +// OSUpgradeProgresses returns an object that can list and get OSUpgradeProgresses. +func (s *oSUpgradeProgressLister) OSUpgradeProgresses(namespace string) OSUpgradeProgressNamespaceLister { + return oSUpgradeProgressNamespaceLister{listers.NewNamespaced[*monok8sv1alpha1.OSUpgradeProgress](s.ResourceIndexer, namespace)} +} + +// OSUpgradeProgressNamespaceLister helps list and get OSUpgradeProgresses. +// All objects returned here must be treated as read-only. +type OSUpgradeProgressNamespaceLister interface { + // List lists all OSUpgradeProgresses in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*monok8sv1alpha1.OSUpgradeProgress, err error) + // Get retrieves the OSUpgradeProgress from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*monok8sv1alpha1.OSUpgradeProgress, error) + OSUpgradeProgressNamespaceListerExpansion +} + +// oSUpgradeProgressNamespaceLister implements the OSUpgradeProgressNamespaceLister +// interface. +type oSUpgradeProgressNamespaceLister struct { + listers.ResourceIndexer[*monok8sv1alpha1.OSUpgradeProgress] +} diff --git a/clitools/pkg/kube/clients.go b/clitools/pkg/kube/clients.go index 6c3a814..38491ac 100644 --- a/clitools/pkg/kube/clients.go +++ b/clitools/pkg/kube/clients.go @@ -3,11 +3,12 @@ package kube import ( "fmt" + monov1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + monoclientset "example.com/monok8s/pkg/generated/clientset/versioned" apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" utilruntime "k8s.io/apimachinery/pkg/util/runtime" kubernetes "k8s.io/client-go/kubernetes" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - monov1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/cli-runtime/pkg/genericclioptions" @@ -21,6 +22,7 @@ type Clients struct { Dynamic dynamic.Interface APIExtensions apiextensionsclientset.Interface RESTClientGetter genericclioptions.RESTClientGetter + MonoKS monoclientset.Interface } func NewClients(flags *genericclioptions.ConfigFlags) (*Clients, error) { @@ -40,7 +42,19 @@ func NewClients(flags *genericclioptions.ConfigFlags) (*Clients, error) { if err != nil { return nil, fmt.Errorf("build apiextensions client: %w", err) } - return &Clients{Config: cfg, Kubernetes: kubeClient, Dynamic: dyn, APIExtensions: ext, RESTClientGetter: flags}, nil + mono, err := monoclientset.NewForConfig(cfg) + if err != nil { + return nil, fmt.Errorf("build monok8s client: %w", err) + } + + return &Clients{ + Config: cfg, + Kubernetes: kubeClient, + Dynamic: dyn, + APIExtensions: ext, + RESTClientGetter: flags, + MonoKS: mono, + }, nil } func NewClientsFromKubeconfig(kubeconfigPath string) (*Clients, error) { diff --git a/clitools/pkg/node/admission.go b/clitools/pkg/node/admission.go new file mode 100644 index 0000000..61b36a4 --- /dev/null +++ b/clitools/pkg/node/admission.go @@ -0,0 +1,400 @@ +package node + +import ( + "context" + "fmt" + "reflect" + "sort" + "strings" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/kubernetes" + "k8s.io/klog/v2" + + monov1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1" + "example.com/monok8s/pkg/kube" + templates "example.com/monok8s/pkg/templates" +) + +func applyAdmissionControllerDeploymentResources(ctx context.Context, n *NodeContext) error { + if strings.TrimSpace(n.Config.Spec.ClusterRole) != "control-plane" || !n.Config.Spec.EnableControlAgent { + klog.InfoS("skipped admission controller deployment", + "clusterRole", n.Config.Spec.ClusterRole, + "enableControlAgent", n.Config.Spec.EnableControlAgent, + ) + return nil + } + + if err := ApplyCRDs(ctx, n); err != nil { + return err + } + + namespace := strings.TrimSpace(n.Config.Namespace) + if namespace == "" { + namespace = templates.DefaultNamespace + } + + clients, err := kube.NewClientsFromKubeconfig(adminKubeconfigPath) + if err != nil { + return fmt.Errorf("build kube clients from %s: %w", adminKubeconfigPath, err) + } + + labels := map[string]string{ + "app.kubernetes.io/name": controlAgentName, + "app.kubernetes.io/component": "controller", + "app.kubernetes.io/part-of": "monok8s", + "app.kubernetes.io/managed-by": "ctl", + } + + kubeClient := clients.Kubernetes + + if err := ensureNamespace(ctx, kubeClient, namespace, labels); err != nil { + return fmt.Errorf("ensure namespace %q: %w", namespace, err) + } + if err := applyAdmissionControllerServiceAccount(ctx, kubeClient, namespace, labels); err != nil { + return fmt.Errorf("apply serviceaccount: %w", err) + } + if err := applyAdmissionControllerClusterRole(ctx, kubeClient, labels); err != nil { + return fmt.Errorf("apply clusterrole: %w", err) + } + if err := applyAdmissionControllerClusterRoleBinding(ctx, kubeClient, namespace, labels); err != nil { + return fmt.Errorf("apply clusterrolebinding: %w", err) + } + if err := applyAdmissionControllerDeployment(ctx, kubeClient, namespace, labels); err != nil { + return fmt.Errorf("apply deployment: %w", err) + } + + return nil +} + +func applyAdmissionControllerServiceAccount(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error { + automount := true + + want := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: controlAgentName, + Namespace: namespace, + Labels: labels, + }, + AutomountServiceAccountToken: &automount, + } + + existing, err := kubeClient.CoreV1().ServiceAccounts(namespace).Get(ctx, controlAgentName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = kubeClient.CoreV1().ServiceAccounts(namespace).Create(ctx, want, metav1.CreateOptions{}) + return err + } + if err != nil { + return err + } + + changed := false + if !reflect.DeepEqual(existing.Labels, want.Labels) { + existing.Labels = want.Labels + changed = true + } + if !reflect.DeepEqual(existing.AutomountServiceAccountToken, want.AutomountServiceAccountToken) { + existing.AutomountServiceAccountToken = want.AutomountServiceAccountToken + changed = true + } + + if !changed { + return nil + } + + _, err = kubeClient.CoreV1().ServiceAccounts(namespace).Update(ctx, existing, metav1.UpdateOptions{}) + return err +} + +func applyAdmissionControllerClusterRole(ctx context.Context, kubeClient kubernetes.Interface, labels map[string]string) error { + wantRules := []rbacv1.PolicyRule{ + { + APIGroups: []string{monov1alpha1.Group}, + Resources: []string{"osupgrades"}, + Verbs: []string{"get", "list", "watch"}, + }, + { + APIGroups: []string{monov1alpha1.Group}, + Resources: []string{"osupgrades/status"}, + Verbs: []string{"get", "patch", "update"}, + }, + { + APIGroups: []string{monov1alpha1.Group}, + Resources: []string{"osupgradeprogresses"}, + Verbs: []string{"get", "list", "watch", "create", "patch", "update"}, + }, + { + APIGroups: []string{""}, + Resources: []string{"nodes"}, + Verbs: []string{"get", "list", "watch"}, + }, + } + + want := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: controlAgentName, + Labels: labels, + }, + Rules: wantRules, + } + + existing, err := kubeClient.RbacV1().ClusterRoles().Get(ctx, controlAgentName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = kubeClient.RbacV1().ClusterRoles().Create(ctx, want, metav1.CreateOptions{}) + return err + } + if err != nil { + return err + } + + changed := false + if !reflect.DeepEqual(existing.Labels, want.Labels) { + existing.Labels = want.Labels + changed = true + } + if !reflect.DeepEqual(existing.Rules, want.Rules) { + existing.Rules = want.Rules + changed = true + } + + if !changed { + return nil + } + + _, err = kubeClient.RbacV1().ClusterRoles().Update(ctx, existing, metav1.UpdateOptions{}) + return err +} + +func applyAdmissionControllerClusterRoleBinding(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error { + wantSubjects := []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: controlAgentName, + Namespace: namespace, + }, + } + + wantRoleRef := rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "ClusterRole", + Name: controlAgentName, + } + + want := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: controlAgentName, + Labels: labels, + }, + Subjects: wantSubjects, + RoleRef: wantRoleRef, + } + + existing, err := kubeClient.RbacV1().ClusterRoleBindings().Get(ctx, controlAgentName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = kubeClient.RbacV1().ClusterRoleBindings().Create(ctx, want, metav1.CreateOptions{}) + return err + } + if err != nil { + return err + } + + changed := false + if !reflect.DeepEqual(existing.Labels, want.Labels) { + existing.Labels = want.Labels + changed = true + } + if !reflect.DeepEqual(existing.Subjects, want.Subjects) { + existing.Subjects = want.Subjects + changed = true + } + if !reflect.DeepEqual(existing.RoleRef, want.RoleRef) { + existing.RoleRef = want.RoleRef + changed = true + } + + if !changed { + return nil + } + + _, err = kubeClient.RbacV1().ClusterRoleBindings().Update(ctx, existing, metav1.UpdateOptions{}) + return err +} + +func applyAdmissionControllerDeployment(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error { + replicas := int32(1) + + selectorLabels := map[string]string{ + "app.kubernetes.io/name": controlAgentName, + "app.kubernetes.io/component": "controller", + } + + podLabels := mergeStringMaps(labels, selectorLabels) + + runAsNonRoot := true + allowPrivilegeEscalation := false + + want := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: controlAgentName, + Namespace: namespace, + Labels: labels, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + Selector: &metav1.LabelSelector{ + MatchLabels: selectorLabels, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: podLabels, + }, + Spec: corev1.PodSpec{ + ServiceAccountName: controlAgentName, + Containers: []corev1.Container{ + { + Name: "controller", + Image: controlAgentImage, + ImagePullPolicy: corev1.PullIfNotPresent, + Args: []string{ + "controller", + }, + Env: []corev1.EnvVar{ + { + Name: "POD_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }, + }, + }, + { + Name: "POD_NAMESPACE", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.namespace", + }, + }, + }, + { + Name: "NODE_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "spec.nodeName", + }, + }, + }, + }, + Ports: []corev1.ContainerPort{ + { + Name: "http", + ContainerPort: 8080, + Protocol: corev1.ProtocolTCP, + }, + }, + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/healthz", + Port: intstr.FromString("http"), + }, + }, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/readyz", + Port: intstr.FromString("http"), + }, + }, + }, + SecurityContext: &corev1.SecurityContext{ + RunAsNonRoot: &runAsNonRoot, + AllowPrivilegeEscalation: &allowPrivilegeEscalation, + }, + }, + }, + }, + }, + }, + } + + existing, err := kubeClient.AppsV1().Deployments(namespace).Get(ctx, controlAgentName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = kubeClient.AppsV1().Deployments(namespace).Create(ctx, want, metav1.CreateOptions{}) + return err + } + if err != nil { + return err + } + + changed := false + if !reflect.DeepEqual(existing.Labels, want.Labels) { + existing.Labels = want.Labels + changed = true + } + if !reflect.DeepEqual(existing.Spec.Replicas, want.Spec.Replicas) { + existing.Spec.Replicas = want.Spec.Replicas + changed = true + } + if !reflect.DeepEqual(existing.Spec.Selector, want.Spec.Selector) { + existing.Spec.Selector = want.Spec.Selector + changed = true + } + if !reflect.DeepEqual(existing.Spec.Template.Labels, want.Spec.Template.Labels) { + existing.Spec.Template.Labels = want.Spec.Template.Labels + changed = true + } + if !reflect.DeepEqual(existing.Spec.Template.Spec.ServiceAccountName, want.Spec.Template.Spec.ServiceAccountName) { + existing.Spec.Template.Spec.ServiceAccountName = want.Spec.Template.Spec.ServiceAccountName + changed = true + } + if !reflect.DeepEqual(existing.Spec.Template.Spec.Containers, want.Spec.Template.Spec.Containers) { + existing.Spec.Template.Spec.Containers = want.Spec.Template.Spec.Containers + changed = true + } + + if !changed { + return nil + } + + _, err = kubeClient.AppsV1().Deployments(namespace).Update(ctx, existing, metav1.UpdateOptions{}) + return err +} + +func mergeStringMaps(maps ...map[string]string) map[string]string { + var total int + for _, m := range maps { + total += len(m) + } + if total == 0 { + return nil + } + + out := make(map[string]string, total) + for _, m := range maps { + for k, v := range m { + out[k] = v + } + } + return out +} + +func sortedKeys(m map[string]string) []string { + if len(m) == 0 { + return nil + } + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} diff --git a/clitools/pkg/node/agent.go b/clitools/pkg/node/agent.go index 924c1ab..13c42d8 100644 --- a/clitools/pkg/node/agent.go +++ b/clitools/pkg/node/agent.go @@ -58,6 +58,9 @@ func ApplyControlAgentDaemonSetResources(ctx context.Context, n *NodeContext) er kubeClient := clients.Kubernetes + if err := ensureNamespace(ctx, kubeClient, namespace, labels); err != nil { + return fmt.Errorf("ensure namespace %q: %w", namespace, err) + } if err := applyControlAgentServiceAccount(ctx, kubeClient, namespace, labels); err != nil { return fmt.Errorf("apply serviceaccount: %w", err) } @@ -74,6 +77,46 @@ func ApplyControlAgentDaemonSetResources(ctx context.Context, n *NodeContext) er return nil } +func ensureNamespace( + ctx context.Context, + kubeClient kubernetes.Interface, + namespace string, + labels map[string]string, +) error { + _, err := kubeClient.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}) + if err == nil { + return nil + } + if !apierrors.IsNotFound(err) { + return fmt.Errorf("get namespace: %w", err) + } + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + Labels: copyStringMap(labels), + }, + } + + _, err = kubeClient.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) + if err != nil && !apierrors.IsAlreadyExists(err) { + return fmt.Errorf("create namespace: %w", err) + } + + return nil +} + +func copyStringMap(in map[string]string) map[string]string { + if len(in) == 0 { + return nil + } + out := make(map[string]string, len(in)) + for k, v := range in { + out[k] = v + } + return out +} + func applyControlAgentServiceAccount(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error { want := &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ @@ -108,16 +151,6 @@ func applyControlAgentServiceAccount(ctx context.Context, kubeClient kubernetes. func applyControlAgentClusterRole(ctx context.Context, kubeClient kubernetes.Interface, labels map[string]string) error { wantRules := []rbacv1.PolicyRule{ - { - APIGroups: []string{monov1alpha1.Group}, - Resources: []string{"osupgrades"}, - Verbs: []string{"get", "list", "watch"}, - }, - { - APIGroups: []string{monov1alpha1.Group}, - Resources: []string{"osupgrades/status"}, - Verbs: []string{"get", "patch", "update"}, - }, { APIGroups: []string{monov1alpha1.Group}, Resources: []string{"osupgradeprogresses"}, diff --git a/clitools/pkg/node/kubeadm.go b/clitools/pkg/node/kubeadm.go index 1de4e0f..5a741a7 100644 --- a/clitools/pkg/node/kubeadm.go +++ b/clitools/pkg/node/kubeadm.go @@ -7,6 +7,7 @@ import ( "fmt" "net" "os" + "sort" "strings" "time" @@ -464,9 +465,57 @@ func buildNodeRegistration(spec monov1alpha1.MonoKSConfigSpec) NodeRegistrationO ) } + labels := effectiveNodeLabels(spec) + if nodeLabels := buildNodeLabelsArg(labels); nodeLabels != "" { + nr.KubeletExtraArgs = append(nr.KubeletExtraArgs, + KubeadmArg{Name: "node-labels", Value: nodeLabels}, + ) + } + return nr } +func effectiveNodeLabels(spec monov1alpha1.MonoKSConfigSpec) map[string]string { + if len(spec.NodeLabels) == 0 && !spec.EnableControlAgent { + return nil + } + + labels := make(map[string]string, len(spec.NodeLabels)+1) + for k, v := range spec.NodeLabels { + labels[k] = v + } + + if spec.EnableControlAgent { + labels[monov1alpha1.ControlAgentKey] = "true" + } + + return labels +} + +func buildNodeLabelsArg(labels map[string]string) string { + if len(labels) == 0 { + return "" + } + + keys := make([]string, 0, len(labels)) + for k := range labels { + k = strings.TrimSpace(k) + if k == "" { + continue + } + keys = append(keys, k) + } + sort.Strings(keys) + + parts := make([]string, 0, len(keys)) + for _, k := range keys { + v := strings.TrimSpace(labels[k]) + parts = append(parts, k+"="+v) + } + + return strings.Join(parts, ",") +} + func maybeAddBootstrapTaint(nr *NodeRegistrationOptions, role string) { if strings.TrimSpace(role) != "worker" { return diff --git a/clitools/pkg/node/metadata.go b/clitools/pkg/node/metadata.go index fd46d3d..e403505 100644 --- a/clitools/pkg/node/metadata.go +++ b/clitools/pkg/node/metadata.go @@ -17,8 +17,8 @@ import ( func ApplyLocalNodeMetadataIfPossible(ctx context.Context, nctx *NodeContext) error { spec := nctx.Config.Spec - if len(spec.NodeAnnotations) == 0 && len(spec.NodeLabels) == 0 { - klog.V(4).Infof("No annotations or labels was defined") + if len(spec.NodeLabels) == 0 { + klog.V(4).Infof("No labels was defined") return nil // nothing to do } @@ -53,9 +53,6 @@ func ApplyLocalNodeMetadataIfPossible(ctx context.Context, nctx *NodeContext) er if node.Labels == nil { node.Labels = make(map[string]string) } - if node.Annotations == nil { - node.Annotations = make(map[string]string) - } // Apply labels for k, v := range spec.NodeLabels { @@ -67,16 +64,11 @@ func ApplyLocalNodeMetadataIfPossible(ctx context.Context, nctx *NodeContext) er node.Labels[monov1alpah1.ControlAgentKey] = controlAgentNodeSelectorValue } - // Apply annotations - for k, v := range spec.NodeAnnotations { - node.Annotations[k] = v - } - _, err = client.CoreV1().Nodes().Update(ctx, node, metav1.UpdateOptions{}) if err != nil { return fmt.Errorf("update node metadata: %w", err) } - klog.Infof("applied labels/annotations to node %q", nodeName) + klog.Infof("applied labels to node %q", nodeName) return nil } diff --git a/clitools/pkg/templates/templates.go b/clitools/pkg/templates/templates.go index 0436941..09d6797 100644 --- a/clitools/pkg/templates/templates.go +++ b/clitools/pkg/templates/templates.go @@ -7,7 +7,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const DefaultNamespace = "kube-system" +const DefaultNamespace = "mono-system" func DefaultMonoKSConfig(v TemplateValues) monov1alpha1.MonoKSConfig { return monov1alpha1.MonoKSConfig{ @@ -51,7 +51,6 @@ func DefaultMonoKSConfig(v TemplateValues) monov1alpha1.MonoKSConfig { SubjectAltNames: copyStringSlice(v.SubjectAltNames), NodeLabels: copyStringMap(v.NodeLabels), - NodeAnnotations: copyStringMap(v.NodeAnnotations), Network: monov1alpha1.NetworkSpec{ Hostname: firstNonEmpty(v.Hostname, v.NodeName), diff --git a/clitools/pkg/templates/values.go b/clitools/pkg/templates/values.go index 1f1fc04..2bda201 100644 --- a/clitools/pkg/templates/values.go +++ b/clitools/pkg/templates/values.go @@ -39,7 +39,6 @@ type TemplateValues struct { SubjectAltNames []string NodeLabels map[string]string - NodeAnnotations map[string]string } func defaultTemplateValues() TemplateValues { @@ -78,9 +77,6 @@ func defaultTemplateValues() TemplateValues { NodeLabels: map[string]string{ monov1alpha1.Label: "value", }, - NodeAnnotations: map[string]string{ - monov1alpha1.Annotation: "value", - }, } } @@ -129,9 +125,6 @@ func LoadTemplateValuesFromEnv() TemplateValues { if m := parseKeyValueMap(os.Getenv("MKS_NODE_LABELS")); len(m) > 0 { v.NodeLabels = m } - if m := parseKeyValueMap(os.Getenv("MKS_NODE_ANNOTATIONS")); len(m) > 0 { - v.NodeAnnotations = m - } return v } diff --git a/configs/cluster.env.default b/configs/cluster.env.default index fa65f24..7e8517c 100644 --- a/configs/cluster.env.default +++ b/configs/cluster.env.default @@ -56,8 +56,7 @@ MKS_CNI_PLUGIN=default # Node registration metadata # Comma-separated key=value pairs -MKS_NODE_LABELS=topology.kubernetes.io/zone=lab,node.kubernetes.io/instance-type=mono-gateway -MKS_NODE_ANNOTATIONS=mono.si/board=ls1046a,monok8s.io/image-version=dev +MKS_NODE_LABELS=topology.kubernetes.io/zone=lab,node.kubernetes.io/instance-type=mono-gateway,mono.si/board=ls1046a # Optional # Extra API server SANs, comma-separated diff --git a/devtools/test-upgrade.sh b/devtools/test-upgrade.sh new file mode 100755 index 0000000..a1dd04e --- /dev/null +++ b/devtools/test-upgrade.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" +OUT_DIR="$( realpath "$SCRIPT_DIR"/../out/ )" + +set -e + +BASE_URL="http://localhost:8000" +TARGET_VERSION="v1.34.6" +STABLE_VERSION="v1.34.6" +NAME="my-upgrade-2" + +echo "apiVersion: monok8s.io/v1alpha1" +echo "kind: OSUpgrade" +echo "metadata:" +echo " name: \"$NAME\"" +echo "spec:" +echo " desiredVersion: \"$TARGET_VERSION\"" +echo " imageURL: \"$BASE_URL/monok8s-$TARGET_VERSION-dev.ext4.zst\"" +echo " nodeSelector: {}" +echo " catalog:" +echo " inline: |" +echo " stable: $STABLE_VERSION" +echo " images:" + +for c in "$OUT_DIR"/catalog-*.txt; do + version=$(grep 'version:' "$c" | awk '{print $3}') + url=$(grep 'url:' "$c" | sed 's/.*"\(.*\)"/\1/') + checksum=$(grep 'checksum:' "$c" | awk '{print $2}') + size=$(grep 'size:' "$c" | awk '{print $2}') + + filename=$(basename "$url") + + echo " - version: $version" + echo " url: $BASE_URL/$filename" + echo " checksum: sha256:$checksum" + echo " size: $size" +done + +echo " blocked:" +echo " - v1.34.0"