From 9494c23045472cfc34bdad7884d22295244bac76 Mon Sep 17 00:00:00 2001 From: Tasko Olevski Date: Wed, 23 Oct 2024 13:30:35 +0200 Subject: [PATCH] feat: single sidecars exe and versioned templates (#745) --- .github/workflows/tests.yaml | 13 - Dockerfile | 6 +- Makefile | 18 +- api/v1alpha1/amaltheasession_children.go | 145 +- api/v1alpha1/amaltheasession_types.go | 12 + api/v1alpha1/auth_templates.go | 110 ++ api/v1alpha1/code_repo_templates.go | 79 ++ api/v1alpha1/zz_generated.deepcopy.go | 16 + authproxy/.gitignore | 42 - authproxy/Dockerfile | 27 - authproxy/Makefile | 122 -- authproxy/cmd/cmd_test.go | 57 - authproxy/cmd/version.go | 40 - authproxy/go.mod | 45 - authproxy/go.sum | 100 -- authproxy/main.go | 24 - bundle.Dockerfile | 2 +- .../amalthea.clusterserviceversion.yaml | 9 +- .../amalthea.dev_amaltheasessions.yaml | 13 + bundle/metadata/annotations.yaml | 2 +- chartpress.yaml | 3 + cloner/.gitignore | 42 - cloner/Dockerfile | 27 - cloner/Makefile | 122 -- cloner/cmd/cmd_test.go | 57 - cloner/cmd/root.go | 41 - cloner/cmd/version.go | 40 - cloner/go.mod | 39 - cloner/go.sum | 155 --- cloner/main.go | 24 - cmd/{ => amalthea}/main.go | 0 cmd/sidecars/main.go | 66 + cmd/sidecars/main_test.go | 90 ++ .../bases/amalthea.dev_amaltheasessions.yaml | 13 + .../bases/amalthea.clusterserviceversion.yaml | 5 +- config/samples/culling-configured.yaml | 2 + controller/crds/amaltheasession.yaml | 302 ---- go.mod | 98 +- go.sum | 263 +++- .../templates/amaltheasession-crd.yaml | 1240 ++++++++++++++--- helm-chart/amalthea-sessions/values.yaml | 1 + helm-chart/amalthea/templates/crd.yaml | 2 +- helm-chart/amalthea/values.yaml | 6 +- {authproxy/cmd => internal/authproxy}/root.go | 56 +- .../cmd => internal/authproxy}/serve.go | 82 +- {cloner/cmd => internal/cloner}/clone.go | 26 +- {cloner/cmd => internal/cloner}/enum_flag.go | 2 +- internal/cloner/root.go | 51 + .../controller/amaltheasession_controller.go | 13 +- .../amaltheasession_controller_test.go | 15 + internal/controller/children.go | 9 +- internal/sidecartemplates/sidecartemplates.go | 83 ++ .../sidecartemplates/sidecartemplates_test.go | 99 ++ sidecars.Dockerfile | 33 + 54 files changed, 2135 insertions(+), 1854 deletions(-) create mode 100644 api/v1alpha1/auth_templates.go create mode 100644 api/v1alpha1/code_repo_templates.go delete mode 100644 authproxy/.gitignore delete mode 100644 authproxy/Dockerfile delete mode 100644 authproxy/Makefile delete mode 100644 authproxy/cmd/cmd_test.go delete mode 100644 authproxy/cmd/version.go delete mode 100644 authproxy/go.mod delete mode 100644 authproxy/go.sum delete mode 100644 authproxy/main.go delete mode 100644 cloner/.gitignore delete mode 100644 cloner/Dockerfile delete mode 100644 cloner/Makefile delete mode 100644 cloner/cmd/cmd_test.go delete mode 100644 cloner/cmd/root.go delete mode 100644 cloner/cmd/version.go delete mode 100644 cloner/go.mod delete mode 100644 cloner/go.sum delete mode 100644 cloner/main.go rename cmd/{ => amalthea}/main.go (100%) create mode 100644 cmd/sidecars/main.go create mode 100644 cmd/sidecars/main_test.go delete mode 100644 controller/crds/amaltheasession.yaml rename {authproxy/cmd => internal/authproxy}/root.go (54%) rename {authproxy/cmd => internal/authproxy}/serve.go (67%) rename {cloner/cmd => internal/cloner}/clone.go (86%) rename {cloner/cmd => internal/cloner}/enum_flag.go (98%) create mode 100644 internal/cloner/root.go create mode 100644 internal/sidecartemplates/sidecartemplates.go create mode 100644 internal/sidecartemplates/sidecartemplates_test.go create mode 100644 sidecars.Dockerfile diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 8fd644da..e7cfbf7a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -25,16 +25,3 @@ jobs: make test-e2e push: never skipContainerUserIdUpdate: false - - run-authproxy-unit-tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Tests - uses: devcontainers/ci@v0.3 - with: - runCmd: | - cd authproxy - make test - push: never - skipContainerUserIdUpdate: false diff --git a/Dockerfile b/Dockerfile index aca26f92..5bf24097 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,16 +12,16 @@ COPY go.sum go.sum RUN go mod download # Copy the go source -COPY cmd/main.go cmd/main.go +COPY cmd/amalthea/main.go cmd/amalthea/main.go COPY api/ api/ -COPY internal/controller/ internal/controller/ +COPY internal/ internal/ # Build # the GOARCH has not a default value to allow the binary be built according to the host where the command # was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO # the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. -RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/amalthea/main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/Makefile b/Makefile index a211892e..1f55348a 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ IMAGE_TAG_BASE ?= renku/amalthea # BUNDLE_IMG defines the image:tag used for the bundle. # You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION) +SIDECARS_IMG ?= $(IMAGE_TAG_BASE)-sidecars:v$(VERSION) # BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) @@ -89,6 +90,8 @@ all: build # More info on the awk command: # http://linuxcommand.org/lc3_adv_awk.php +HELM_CRD_TEMPLATE ?= helm-chart/amalthea-sessions/templates/amaltheasession-crd.yaml + .PHONY: help help: ## Display this help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) @@ -98,6 +101,9 @@ help: ## Display this help. .PHONY: manifests manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases + echo "{{- if .Values.deployCrd -}}" > $(HELM_CRD_TEMPLATE) + echo "# This manifest is auto-generated from the makefile do not edit manually." >> $(HELM_CRD_TEMPLATE) + cat config/crd/bases/*yaml >> $(HELM_CRD_TEMPLATE) .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. @@ -140,11 +146,19 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes .PHONY: build build: manifests generate fmt vet ## Build manager binary. - go build -o bin/manager cmd/main.go + go build -o bin/manager cmd/amalthea/main.go + +.PHONY: build-sidecars +build-sidecars: fmt vet + go build -o bin/sidecars cmd/sidecars/main.go + +.PHONY: build-sidecars +docker-build-sidecars: build-sidecars + $(CONTAINER_TOOL) build -t ${SIDECARS_IMG} -f sidecars.Dockerfile . .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go + go run ./cmd/amalthea/main.go # If you wish to build the manager image targeting other platforms you can use the --platform flag. # (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. diff --git a/api/v1alpha1/amaltheasession_children.go b/api/v1alpha1/amaltheasession_children.go index f3b595ab..dc54d52c 100644 --- a/api/v1alpha1/amaltheasession_children.go +++ b/api/v1alpha1/amaltheasession_children.go @@ -5,7 +5,6 @@ import ( "fmt" "net/url" "os" - "strings" "time" appsv1 "k8s.io/api/apps/v1" @@ -29,8 +28,6 @@ const servicePort int32 = 80 const sessionVolumeName string = prefix + "volume" const shmVolumeName string = prefix + "dev-shm" const authProxyPort int32 = 65535 -const oauth2ProxyImage = "bitnami/oauth2-proxy:7.6.0" -const authProxyImage = "renku/authproxy:0.0.1-test-1" var rcloneStorageClass string = getStorageClass() var rcloneDefaultStorage resource.Quantity = resource.MustParse("1Gi") @@ -38,7 +35,7 @@ var rcloneDefaultStorage resource.Quantity = resource.MustParse("1Gi") const rcloneStorageSecretNameAnnotation = "csi-rclone.dev/secretName" // StatefulSet returns a AmaltheaSession StatefulSet object -func (cr *AmaltheaSession) StatefulSet() appsv1.StatefulSet { +func (cr *AmaltheaSession) StatefulSet() (appsv1.StatefulSet, error) { labels := labelsForAmaltheaSession(cr.Name) replicas := int32(1) if cr.Spec.Hibernated { @@ -104,9 +101,13 @@ func (cr *AmaltheaSession) StatefulSet() appsv1.StatefulSet { initContainers := []v1.Container{} if len(cr.Spec.CodeRepositories) > 0 { - gitCloneContainers, gitCloneVols := cr.initClones() - initContainers = append(initContainers, gitCloneContainers...) - volumes = append(volumes, gitCloneVols...) + templateFunc, err := initCloneTemplate.GetFunc(cr.Spec.Sidecars.Image) + if err != nil { + return appsv1.StatefulSet{}, err + } + cloneManifests := templateFunc(cr) + initContainers = append(initContainers, cloneManifests.Containers...) + volumes = append(volumes, cloneManifests.Volumes...) } initContainers = append(initContainers, cr.Spec.ExtraInitContainers...) @@ -141,84 +142,13 @@ func (cr *AmaltheaSession) StatefulSet() appsv1.StatefulSet { containers := []v1.Container{sessionContainer} containers = append(containers, cr.Spec.ExtraContainers...) - if auth := cr.Spec.Authentication; auth != nil && auth.Enabled { - extraAuthMounts := []v1.VolumeMount{} - if len(auth.ExtraVolumeMounts) > 0 { - extraAuthMounts = auth.ExtraVolumeMounts - } - volumes = append(volumes, v1.Volume{ - Name: "proxy-configuration-secret", - VolumeSource: v1.VolumeSource{ - Secret: &v1.SecretVolumeSource{ - SecretName: auth.SecretRef.Name, - Optional: ptr.To(false), - }, - }, - }) - - if auth.Type == Oidc { - sessionURL := cr.sessionLocalhostURL().String() - if !strings.HasSuffix(sessionURL, "/") { - // NOTE: If the url does not end with "/" then the oauth2proxy proxies only the exact path - // and does not proxy subpaths - sessionURL += "/" - } - authContainer := v1.Container{ - Image: oauth2ProxyImage, - Name: "oauth2-proxy", - SecurityContext: &v1.SecurityContext{ - AllowPrivilegeEscalation: ptr.To(false), - RunAsNonRoot: ptr.To(true), - }, - Args: []string{ - fmt.Sprintf("--upstream=%s", sessionURL), - fmt.Sprintf("--http-address=:%d", authProxyPort), - "--silence-ping-logging", - "--config=/etc/oauth2-proxy/" + auth.SecretRef.Key, - }, - VolumeMounts: append( - []v1.VolumeMount{ - { - Name: "proxy-configuration-secret", - MountPath: "/etc/oauth2-proxy", - }, - }, - extraAuthMounts..., - ), - } - - containers = append(containers, authContainer) - } else if auth.Type == Token { - authContainer := v1.Container{ - Image: authProxyImage, - Name: "authproxy", - SecurityContext: &v1.SecurityContext{ - AllowPrivilegeEscalation: ptr.To(false), - RunAsNonRoot: ptr.To(true), - RunAsUser: ptr.To(int64(1000)), - RunAsGroup: ptr.To(int64(1000)), - }, - Args: []string{"serve", "--config", "/etc/authproxy/" + auth.SecretRef.Key}, - Env: []v1.EnvVar{ - {Name: "AUTHPROXY_PORT", Value: fmt.Sprintf("%d", authProxyPort)}, - // NOTE: The url for the remote has to not have a path at all, if it does, then the path - // in the url is appended to any path that is already there when the request comes in. - {Name: "AUTHPROXY_REMOTE", Value: fmt.Sprintf("http://127.0.0.1:%d", cr.Spec.Session.Port)}, - }, - VolumeMounts: append( - []v1.VolumeMount{ - { - Name: "proxy-configuration-secret", - MountPath: "/etc/authproxy", - }, - }, - extraAuthMounts..., - ), - } - - containers = append(containers, authContainer) - } + authTemplateFn, err := authTemplate.GetFunc(cr.Spec.Sidecars.Image) + if err != nil { + return appsv1.StatefulSet{}, err } + authManifests := authTemplateFn(cr) + containers = append(containers, authManifests.Containers...) + volumes = append(volumes, authManifests.Volumes...) sts := appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ @@ -249,7 +179,7 @@ func (cr *AmaltheaSession) StatefulSet() appsv1.StatefulSet { }, }, } - return sts + return sts, nil } // Service returns a AmaltheaSession Service object @@ -407,51 +337,6 @@ func (cr *AmaltheaSession) Pod(ctx context.Context, clnt client.Client) (*v1.Pod return &pod, err } -// Generates the init containers that clones the specified Git repositories -func (cr *AmaltheaSession) initClones() ([]v1.Container, []v1.Volume) { - envVars := []v1.EnvVar{} - volMounts := []v1.VolumeMount{{Name: sessionVolumeName, MountPath: cr.Spec.Session.Storage.MountPath}} - vols := []v1.Volume{} - containers := []v1.Container{} - - for irepo, repo := range cr.Spec.CodeRepositories { - args := []string{"clone", "--strategy", "notifexist", "--remote", repo.Remote, "--path", cr.Spec.Session.Storage.MountPath + "/" + repo.ClonePath} - - if repo.CloningConfigSecretRef != nil { - secretVolName := fmt.Sprintf("git-clone-cred-volume-%d", irepo) - secretMountPath := "/git-clone-secrets" - secretFilePath := fmt.Sprintf("%s/%s", secretMountPath, repo.CloningConfigSecretRef.Key) - vols = append( - vols, - v1.Volume{ - Name: secretVolName, - VolumeSource: v1.VolumeSource{Secret: &v1.SecretVolumeSource{SecretName: repo.CloningConfigSecretRef.Name}}, - }, - ) - volMounts = append(volMounts, v1.VolumeMount{Name: secretVolName, MountPath: secretMountPath}) - - args = append(args, []string{"--config", secretFilePath}...) - } - - if repo.Revision != "" { - args = append(args, []string{"--revision", repo.Revision}...) - } - - gitCloneContainerName := fmt.Sprintf("git-clone-%d", irepo) - containers = append(containers, v1.Container{ - Name: gitCloneContainerName, - Image: "renku/cloner:0.0.1", - VolumeMounts: volMounts, - WorkingDir: cr.Spec.Session.Storage.MountPath, - Env: envVars, - SecurityContext: &v1.SecurityContext{RunAsUser: &cr.Spec.Session.RunAsUser, RunAsGroup: &cr.Spec.Session.RunAsGroup}, - Args: args, - }) - } - - return containers, vols -} - // Returns the list of all the secrets used in this CR func (cr *AmaltheaSession) AdoptedSecrets() v1.SecretList { secrets := v1.SecretList{} diff --git a/api/v1alpha1/amaltheasession_types.go b/api/v1alpha1/amaltheasession_types.go index e8326039..eb87d5f6 100644 --- a/api/v1alpha1/amaltheasession_types.go +++ b/api/v1alpha1/amaltheasession_types.go @@ -86,6 +86,9 @@ type AmaltheaSessionSpec struct { // Passed right through to the Statefulset used for the session. // +optional Tolerations []v1.Toleration `json:"tolerations,omitempty"` + + //Control over the sidecars and init containers Amalthea adds to each session + Sidecars Sidecars `json:"sidecars,omitempty"` } type Session struct { @@ -416,3 +419,12 @@ func (a *AmaltheaSession) GetURL() *url.URL { } return &sessionURL } + +type Sidecars struct { + // The docker image with the sidecars CLI. + // The containers that are templated are decided based on the image version tag, falling back + // on the latest templates for the latest version. Using a non-official image here is strongly + // discouraged, if you must then you should use the same semver tags as the official image you + // started with or based your custom image on. + Image string `json:"image,omitempty"` +} diff --git a/api/v1alpha1/auth_templates.go b/api/v1alpha1/auth_templates.go new file mode 100644 index 00000000..54def823 --- /dev/null +++ b/api/v1alpha1/auth_templates.go @@ -0,0 +1,110 @@ +package v1alpha1 + +import ( + "fmt" + "strings" + + "github.com/Masterminds/semver/v3" + st "github.com/SwissDataScienceCenter/amalthea/internal/sidecartemplates" + v1 "k8s.io/api/core/v1" + "k8s.io/utils/ptr" +) + +// NOTE: changing the code of the template for an existing version after it has been released +// may result in the restart of all old sessions that are running when the new version of amalthea +// is deployed. +var authTemplate st.VersionedTemplates[AmaltheaSession, manifests] = st.NewVersionedTemplates( + st.VersionedTemplate[AmaltheaSession, manifests]{ + MinInclusiveVersion: *semver.MustParse("0.0.1"), + TemplateFunc: func(session *AmaltheaSession) manifests { + output := manifests{} + volumeMounts := []v1.VolumeMount{} + auth := session.Spec.Authentication + + if auth == nil || !auth.Enabled { + return output + } + if len(auth.ExtraVolumeMounts) > 0 { + volumeMounts = auth.ExtraVolumeMounts + } + output.Volumes = append(output.Volumes, v1.Volume{ + Name: "proxy-configuration-secret", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: auth.SecretRef.Name, + Optional: ptr.To(false), + }, + }, + }) + + if auth.Type == Oidc { + sessionURL := session.sessionLocalhostURL().String() + if !strings.HasSuffix(sessionURL, "/") { + // NOTE: If the url does not end with "/" then the oauth2proxy proxies only the exact path + // and does not proxy subpaths + sessionURL += "/" + } + authContainer := v1.Container{ + Image: "bitnami/oauth2-proxy:7.6.0", + Name: "oauth2-proxy", + SecurityContext: &v1.SecurityContext{ + AllowPrivilegeEscalation: ptr.To(false), + RunAsNonRoot: ptr.To(true), + }, + Args: []string{ + fmt.Sprintf("--upstream=%s", sessionURL), + fmt.Sprintf("--http-address=:%d", authProxyPort), + "--silence-ping-logging", + "--config=/etc/oauth2-proxy/" + auth.SecretRef.Key, + }, + VolumeMounts: append( + []v1.VolumeMount{ + { + Name: "proxy-configuration-secret", + MountPath: "/etc/oauth2-proxy", + }, + }, + volumeMounts..., + ), + } + + output.Containers = append(output.Containers, authContainer) + } else if auth.Type == Token { + authContainer := v1.Container{ + Image: session.Spec.Sidecars.Image, + Name: "authproxy", + SecurityContext: &v1.SecurityContext{ + AllowPrivilegeEscalation: ptr.To(false), + RunAsNonRoot: ptr.To(true), + RunAsUser: ptr.To(int64(1000)), + RunAsGroup: ptr.To(int64(1000)), + }, + Args: []string{ + "proxy", + "serve", + "--config", + fmt.Sprintf("/etc/authproxy/%s", auth.SecretRef.Key), + }, + Env: []v1.EnvVar{ + {Name: "AUTHPROXY_PORT", Value: fmt.Sprintf("%d", authProxyPort)}, + // NOTE: The url for the remote has to not have a path at all, if it does, then the path + // in the url is appended to any path that is already there when the request comes in. + {Name: "AUTHPROXY_REMOTE", Value: fmt.Sprintf("http://127.0.0.1:%d", session.Spec.Session.Port)}, + }, + VolumeMounts: append( + []v1.VolumeMount{ + { + Name: "proxy-configuration-secret", + MountPath: "/etc/authproxy", + }, + }, + volumeMounts..., + ), + } + + output.Containers = append(output.Containers, authContainer) + } + return output + }, + }, +) diff --git a/api/v1alpha1/code_repo_templates.go b/api/v1alpha1/code_repo_templates.go new file mode 100644 index 00000000..01f7d1b9 --- /dev/null +++ b/api/v1alpha1/code_repo_templates.go @@ -0,0 +1,79 @@ +package v1alpha1 + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + st "github.com/SwissDataScienceCenter/amalthea/internal/sidecartemplates" + v1 "k8s.io/api/core/v1" +) + +type manifests struct { + Containers []v1.Container + Volumes []v1.Volume +} + +// NOTE: changing the code of the template for an existing version after it has been released +// may result in the restart of all old sessions that are running when the new version of amalthea +// is deployed. +var initCloneTemplate st.VersionedTemplates[AmaltheaSession, manifests] = st.NewVersionedTemplates( + st.VersionedTemplate[AmaltheaSession, manifests]{ + MinInclusiveVersion: *semver.MustParse("0.0.1"), + TemplateFunc: func(session *AmaltheaSession) manifests { + envVars := []v1.EnvVar{} + volMounts := []v1.VolumeMount{{Name: sessionVolumeName, MountPath: session.Spec.Session.Storage.MountPath}} + vols := []v1.Volume{} + containers := []v1.Container{} + + for irepo, repo := range session.Spec.CodeRepositories { + args := []string{ + "cloner", + "clone", + "--strategy", + "notifexist", + "--remote", + repo.Remote, + "--path", + fmt.Sprintf("%s/%s", session.Spec.Session.Storage.MountPath, repo.ClonePath), + } + + if repo.CloningConfigSecretRef != nil { + secretVolName := fmt.Sprintf("git-clone-cred-volume-%d", irepo) + secretMountPath := "/git-clone-secrets" + secretFilePath := fmt.Sprintf("%s/%s", secretMountPath, repo.CloningConfigSecretRef.Key) + vols = append( + vols, + v1.Volume{ + Name: secretVolName, + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{SecretName: repo.CloningConfigSecretRef.Name}, + }, + }, + ) + volMounts = append(volMounts, v1.VolumeMount{Name: secretVolName, MountPath: secretMountPath}) + + args = append(args, []string{"--config", secretFilePath}...) + } + + if repo.Revision != "" { + args = append(args, []string{"--revision", repo.Revision}...) + } + + gitCloneContainerName := fmt.Sprintf("git-clone-%d", irepo) + containers = append(containers, v1.Container{ + Name: gitCloneContainerName, + Image: session.Spec.Sidecars.Image, + VolumeMounts: volMounts, + WorkingDir: session.Spec.Session.Storage.MountPath, + Env: envVars, + SecurityContext: &v1.SecurityContext{ + RunAsUser: &session.Spec.Session.RunAsUser, + RunAsGroup: &session.Spec.Session.RunAsGroup, + }, + Args: args, + }) + } + return manifests{Containers: containers, Volumes: vols} + }, + }, +) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 25446fe1..c0c3ab07 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -169,6 +169,7 @@ func (in *AmaltheaSessionSpec) DeepCopyInto(out *AmaltheaSessionSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + out.Sidecars = in.Sidecars } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AmaltheaSessionSpec. @@ -419,6 +420,21 @@ func (in *SessionSecretRef) DeepCopy() *SessionSecretRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Sidecars) DeepCopyInto(out *Sidecars) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sidecars. +func (in *Sidecars) DeepCopy() *Sidecars { + if in == nil { + return nil + } + out := new(Sidecars) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Storage) DeepCopyInto(out *Storage) { *out = *in diff --git a/authproxy/.gitignore b/authproxy/.gitignore deleted file mode 100644 index 69fc3579..00000000 --- a/authproxy/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright 2024. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work -go.work.sum - -# env file -.env - -# Output folder -bin/ \ No newline at end of file diff --git a/authproxy/Dockerfile b/authproxy/Dockerfile deleted file mode 100644 index 876833df..00000000 --- a/authproxy/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -# Build the application from source -FROM golang:1.22 AS build-stage - -WORKDIR /app - -COPY go.mod go.sum ./ -RUN go mod download - -COPY *.go ./ -COPY cmd ./cmd - -RUN CGO_ENABLED=0 GOOS=linux go build -o /authproxy - -# Run the tests in the container -FROM build-stage AS run-test-stage -RUN go test -v ./... - -# Deploy the application binary into a lean image -FROM gcr.io/distroless/base-debian12 AS build-release-stage - -WORKDIR / - -COPY --from=build-stage /authproxy /authproxy - -USER nonroot:nonroot - -ENTRYPOINT ["/authproxy"] diff --git a/authproxy/Makefile b/authproxy/Makefile deleted file mode 100644 index 58b600f0..00000000 --- a/authproxy/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright 2024. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# VERSION defines the project version for the bundle. -# Update this value when you upgrade the version of your project. -# To re-generate a bundle for another specific version without changing the standard setup, you can: -# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) -# - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.0.1 -LDFLAGS="-X 'authproxy/cmd.Version=v$(VERSION)'" - -# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. -# This variable is used to construct full image tags for bundle and catalog images. -# -# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both -# amalthea.dev/amalthea-bundle:$VERSION and amalthea.dev/amalthea-catalog:$VERSION. -IMAGE_TAG_BASE ?= renku/authproxy -IMG ?= $(IMAGE_TAG_BASE):$(VERSION) - -# CONTAINER_TOOL defines the container tool to be used for building images. -# Be aware that the target commands are only tested with Docker which is -# scaffolded by default. However, you might want to replace it to use other -# tools. (i.e. podman) -CONTAINER_TOOL ?= docker - -# Setting SHELL to bash allows bash commands to be executed by recipes. -# Options are set to exit when a recipe line exits non-zero or a piped command fails. -SHELL = /usr/bin/env bash -o pipefail -.SHELLFLAGS = -ec - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -.PHONY: all -all: mod test vet fmt build run - -##@ Run - -.PHONY: -run: fmt vet build run ## Run the proxy - chmod +x bin/authproxy - ./bin/authproxy - -.PHONY: install -install: run ## Install the proxy - go install -v ./... - -##@ QA - -.PHONY: audit -audit: ## Run quality control checks - go mod verify - go vet ./... - go run honnef.co/go/tools/cmd/staticcheck@latest -checks=all,-ST1000,-U1000 ./... - go run golang.org/x/vuln/cmd/govulncheck@latest ./... - -.PHONY: test -test: build ## Run tests - go test $$(go list ./... | grep -v /e2e) -race -buildvcs - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: mod -mod: ## Tidy mods - go mod tidy - -.PHONY: code-cleanup -code-cleanup: vet fmt mod ## Code cleanup - -##@ Build - -.PHONY: build -build: fmt vet - go build -ldflags=$(LDFLAGS) -o bin/authproxy main.go - -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v3-builder - rm Dockerfile.cross diff --git a/authproxy/cmd/cmd_test.go b/authproxy/cmd/cmd_test.go deleted file mode 100644 index f38bdadd..00000000 --- a/authproxy/cmd/cmd_test.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2024. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cmd_test - -import ( - "bytes" - "context" - "strings" - "testing" - - "os/exec" - - "github.com/stretchr/testify/assert" -) - -var ( - AuthProxyPath = "../bin/authproxy" -) - -func runCommandWithContext(ctx context.Context, t *testing.T, cmd, args string, env ...string) (bytes.Buffer, error) { - var combinedOutput bytes.Buffer - - command := exec.CommandContext(ctx, cmd, strings.Fields(args)...) - command.Stdout = &combinedOutput - command.Stderr = &combinedOutput - - command.Env = append(command.Env, env...) - - t.Logf("Running %q with env: %v\n", command.String(), command.Env) - - return combinedOutput, command.Run() -} - -func TestVersion(t *testing.T) { - assert := assert.New(t) - - ctx := context.Background() - output, err := runCommandWithContext(ctx, t, AuthProxyPath, "version") - assert.Nil(err, nil, "version command failed") - out := output.String() - - assert.NotContains(out, "development") -} diff --git a/authproxy/cmd/version.go b/authproxy/cmd/version.go deleted file mode 100644 index cf361427..00000000 --- a/authproxy/cmd/version.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2024. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -var ( - Version = "development" -) - -func init() { - rootCmd.AddCommand(versionCmd) -} - -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Print the version number of proxyauth", - Long: `All software has versions. This is proxyauth's`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("proxyauth", Version) - }, -} diff --git a/authproxy/go.mod b/authproxy/go.mod deleted file mode 100644 index 78276b0b..00000000 --- a/authproxy/go.mod +++ /dev/null @@ -1,45 +0,0 @@ -module authproxy - -go 1.22.5 - -require ( - github.com/labstack/echo/v4 v4.12.0 - github.com/labstack/gommon v0.4.2 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.19.0 -) - -require ( - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/stretchr/testify v1.9.0 // indirect - github.com/subosito/gotenv v1.6.0 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/time v0.5.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/authproxy/go.sum b/authproxy/go.sum deleted file mode 100644 index 7700faf8..00000000 --- a/authproxy/go.sum +++ /dev/null @@ -1,100 +0,0 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= -github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= -github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= -github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -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/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= -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= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -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.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -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.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -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= diff --git a/authproxy/main.go b/authproxy/main.go deleted file mode 100644 index ee43b3bc..00000000 --- a/authproxy/main.go +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright 2024. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -package main - -import ( - "authproxy/cmd" -) - -func main() { - cmd.Execute() -} diff --git a/bundle.Dockerfile b/bundle.Dockerfile index eacfcd83..52082b9f 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=amalthea LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.35.0 +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.36.1 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 diff --git a/bundle/manifests/amalthea.clusterserviceversion.yaml b/bundle/manifests/amalthea.clusterserviceversion.yaml index 2d7d5774..4bc7be63 100644 --- a/bundle/manifests/amalthea.clusterserviceversion.yaml +++ b/bundle/manifests/amalthea.clusterserviceversion.yaml @@ -21,8 +21,8 @@ metadata: } ] capabilities: Basic Install - createdAt: "2024-10-09T09:14:53Z" - operators.operatorframework.io/builder: operator-sdk-v1.35.0 + createdAt: "2024-10-09T13:22:54Z" + operators.operatorframework.io/builder: operator-sdk-v1.36.1 operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 name: amalthea.v0.0.1 namespace: placeholder @@ -35,8 +35,9 @@ spec: kind: AmaltheaSession name: amaltheasessions.amalthea.dev statusDescriptors: - - description: Conditions store the status conditions of the AmaltheaSessions. - This is a standard thing that many operators implement see https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + - description: |- + Conditions store the status conditions of the AmaltheaSessions. This is a standard thing that + many operators implement see https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties displayName: Conditions path: conditions version: v1alpha1 diff --git a/bundle/manifests/amalthea.dev_amaltheasessions.yaml b/bundle/manifests/amalthea.dev_amaltheasessions.yaml index c236c76c..663ce382 100644 --- a/bundle/manifests/amalthea.dev_amaltheasessions.yaml +++ b/bundle/manifests/amalthea.dev_amaltheasessions.yaml @@ -5640,6 +5640,19 @@ spec: - image - port type: object + sidecars: + description: Control over the sidecars and init containers Amalthea + adds to each session + properties: + image: + description: |- + The docker image with the sidecars CLI. + The containers that are templated are decided based on the image version tag, falling back + on the latest templates for the latest version. Using a non-official image here is strongly + discouraged, if you must then you should use the same semver tags as the official image you + started with or based your custom image on. + type: string + type: object tolerations: description: |- If specified, the pod's tolerations. diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index 6902db2c..06765447 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -5,7 +5,7 @@ annotations: operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: amalthea operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.metrics.builder: operator-sdk-v1.35.0 + operators.operatorframework.io.metrics.builder: operator-sdk-v1.36.1 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4 diff --git a/chartpress.yaml b/chartpress.yaml index 43ce340a..b09aa902 100644 --- a/chartpress.yaml +++ b/chartpress.yaml @@ -25,3 +25,6 @@ charts: contextPath: . dockerfilePath: Dockerfile valuesPath: controllerManager.manager.image + sidecars: + contextPath: . + dockerfilePath: sidecars.Dockerfile diff --git a/cloner/.gitignore b/cloner/.gitignore deleted file mode 100644 index 69fc3579..00000000 --- a/cloner/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright 2024. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work -go.work.sum - -# env file -.env - -# Output folder -bin/ \ No newline at end of file diff --git a/cloner/Dockerfile b/cloner/Dockerfile deleted file mode 100644 index d9397828..00000000 --- a/cloner/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -# Build the application from source -FROM golang:1.22 AS build-stage - -WORKDIR /app - -COPY go.mod go.sum ./ -RUN go mod download - -COPY *.go ./ -COPY cmd ./cmd - -RUN CGO_ENABLED=0 GOOS=linux go build -o /cloner - -# Run the tests in the container -FROM build-stage AS run-test-stage -RUN go test -v ./... - -# Deploy the application binary into a lean image -FROM gcr.io/distroless/base-debian12 AS build-release-stage - -WORKDIR / - -COPY --from=build-stage /cloner /cloner - -USER nonroot:nonroot - -ENTRYPOINT ["/cloner"] diff --git a/cloner/Makefile b/cloner/Makefile deleted file mode 100644 index 5e055723..00000000 --- a/cloner/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright 2024. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# VERSION defines the project version for the bundle. -# Update this value when you upgrade the version of your project. -# To re-generate a bundle for another specific version without changing the standard setup, you can: -# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) -# - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.0.1 -LDFLAGS="-X 'cloner/cmd.Version=v$(VERSION)'" - -# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. -# This variable is used to construct full image tags for bundle and catalog images. -# -# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both -# amalthea.dev/amalthea-bundle:$VERSION and amalthea.dev/amalthea-catalog:$VERSION. -IMAGE_TAG_BASE ?= renku/cloner -IMG ?= $(IMAGE_TAG_BASE):$(VERSION) - -# CONTAINER_TOOL defines the container tool to be used for building images. -# Be aware that the target commands are only tested with Docker which is -# scaffolded by default. However, you might want to replace it to use other -# tools. (i.e. podman) -CONTAINER_TOOL ?= docker - -# Setting SHELL to bash allows bash commands to be executed by recipes. -# Options are set to exit when a recipe line exits non-zero or a piped command fails. -SHELL = /usr/bin/env bash -o pipefail -.SHELLFLAGS = -ec - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -.PHONY: all -all: mod test vet fmt build run - -##@ Run - -.PHONY: -run: fmt vet build run ## Run the proxy - chmod +x bin/cloner - ./bin/cloner - -.PHONY: install -install: run ## Install the proxy - go install -v ./... - -##@ QA - -.PHONY: audit -audit: ## Run quality control checks - go mod verify - go vet ./... - go run honnef.co/go/tools/cmd/staticcheck@latest -checks=all,-ST1000,-U1000 ./... - go run golang.org/x/vuln/cmd/govulncheck@latest ./... - -.PHONY: test -test: build ## Run tests - go test $$(go list ./... | grep -v /e2e) -race -buildvcs - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: mod -mod: ## Tidy mods - go mod tidy - -.PHONY: code-cleanup -code-cleanup: vet fmt mod ## Code cleanup - -##@ Build - -.PHONY: build -build: fmt vet - go build -ldflags=$(LDFLAGS) -o bin/cloner main.go - -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v3-builder - rm Dockerfile.cross diff --git a/cloner/cmd/cmd_test.go b/cloner/cmd/cmd_test.go deleted file mode 100644 index f38bdadd..00000000 --- a/cloner/cmd/cmd_test.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2024. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cmd_test - -import ( - "bytes" - "context" - "strings" - "testing" - - "os/exec" - - "github.com/stretchr/testify/assert" -) - -var ( - AuthProxyPath = "../bin/authproxy" -) - -func runCommandWithContext(ctx context.Context, t *testing.T, cmd, args string, env ...string) (bytes.Buffer, error) { - var combinedOutput bytes.Buffer - - command := exec.CommandContext(ctx, cmd, strings.Fields(args)...) - command.Stdout = &combinedOutput - command.Stderr = &combinedOutput - - command.Env = append(command.Env, env...) - - t.Logf("Running %q with env: %v\n", command.String(), command.Env) - - return combinedOutput, command.Run() -} - -func TestVersion(t *testing.T) { - assert := assert.New(t) - - ctx := context.Background() - output, err := runCommandWithContext(ctx, t, AuthProxyPath, "version") - assert.Nil(err, nil, "version command failed") - out := output.String() - - assert.NotContains(out, "development") -} diff --git a/cloner/cmd/root.go b/cloner/cmd/root.go deleted file mode 100644 index c7a0d7be..00000000 --- a/cloner/cmd/root.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2024. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cmd - -import ( - "github.com/spf13/cobra" -) - -var ( - rootCmd = &cobra.Command{ - Use: "cloner", - Short: "A small utility to clone repositories", - Long: `cloner is a helper to Amalthea to clone project -related repositories`, - } -) - -func Execute() error { - return rootCmd.Execute() -} - -func init() { - cobra.OnInitialize(initConfig) -} - -func initConfig() { -} diff --git a/cloner/cmd/version.go b/cloner/cmd/version.go deleted file mode 100644 index cf361427..00000000 --- a/cloner/cmd/version.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2024. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -var ( - Version = "development" -) - -func init() { - rootCmd.AddCommand(versionCmd) -} - -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Print the version number of proxyauth", - Long: `All software has versions. This is proxyauth's`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("proxyauth", Version) - }, -} diff --git a/cloner/go.mod b/cloner/go.mod deleted file mode 100644 index e3118e23..00000000 --- a/cloner/go.mod +++ /dev/null @@ -1,39 +0,0 @@ -module cloner - -go 1.22.5 - -require ( - github.com/go-git/go-git/v5 v5.12.0 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 - gopkg.in/yaml.v3 v3.0.1 -) - -require ( - dario.cat/mergo v1.0.0 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v1.0.0 // indirect - github.com/cloudflare/circl v1.3.7 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emirpasic/gods v1.18.1 // indirect - github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/skeema/knownhosts v1.2.2 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/tools v0.13.0 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect -) diff --git a/cloner/go.sum b/cloner/go.sum deleted file mode 100644 index d20002e4..00000000 --- a/cloner/go.sum +++ /dev/null @@ -1,155 +0,0 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= -github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -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/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cloner/main.go b/cloner/main.go deleted file mode 100644 index 57d72f3c..00000000 --- a/cloner/main.go +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright 2024. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -package main - -import ( - "cloner/cmd" -) - -func main() { - cmd.Execute() -} diff --git a/cmd/main.go b/cmd/amalthea/main.go similarity index 100% rename from cmd/main.go rename to cmd/amalthea/main.go diff --git a/cmd/sidecars/main.go b/cmd/sidecars/main.go new file mode 100644 index 00000000..76cdfa9c --- /dev/null +++ b/cmd/sidecars/main.go @@ -0,0 +1,66 @@ +/* +Copyright 2024. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import ( + "runtime/debug" + + "github.com/SwissDataScienceCenter/amalthea/internal/authproxy" + "github.com/SwissDataScienceCenter/amalthea/internal/cloner" + "github.com/spf13/cobra" +) + +func buildCommands() *cobra.Command { + var rootCmd = &cobra.Command{ + Short: "Amalthea sidecar utilities", + Long: "Amalthea sidecar utilities", + } + var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print the version number of the sidecar executable", + Run: func(cmd *cobra.Command, args []string) { + version := "(devel)" + info, ok := debug.ReadBuildInfo() + if ok && len(info.Main.Version) > 0 { + version = info.Main.Version + } + cmd.Println("sidecars", version) + }, + } + proxyRoot := &cobra.Command{ + Use: "proxy serve", + Short: "Authentication proxy", + } + clonerRoot := &cobra.Command{ + Use: "cloner clone", + Short: "Cloning utilities", + } + rootCmd.AddCommand(versionCmd) + authCmd, err := authproxy.Command() + cobra.CheckErr(err) + clonerCmd, err := cloner.Command() + cobra.CheckErr(err) + proxyRoot.AddCommand(authCmd) + clonerRoot.AddCommand(clonerCmd) + rootCmd.AddCommand(proxyRoot) + rootCmd.AddCommand(clonerRoot) + return rootCmd +} + +func main() { + cmd := buildCommands() + cobra.CheckErr(cmd.Execute()) +} diff --git a/cmd/sidecars/main_test.go b/cmd/sidecars/main_test.go new file mode 100644 index 00000000..3e87b8d0 --- /dev/null +++ b/cmd/sidecars/main_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2024. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bytes" + "fmt" + "io" + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" +) + +func mapOutput(cmd *cobra.Command, out io.Writer, errOut io.Writer) { + if cmd == nil { + return + } + if out != nil { + cmd.SetOut(out) + } + if errOut != nil { + cmd.SetErr(errOut) + } +} + +func readCloseOutput(out io.Reader, errOut io.Reader) (string, string, error) { + var stdout, stderr []byte + var err error + if out != nil { + stdout, err = io.ReadAll(out) + if err != nil { + return "", "", err + } + } + if errOut != nil { + stderr, err = io.ReadAll(errOut) + if err != nil { + return "", "", err + } + } + return string(stdout), string(stderr), nil +} + +func TestVersion(t *testing.T) { + assert := assert.New(t) + stdoutBuf := bytes.NewBufferString("") + stderrBuf := bytes.NewBufferString("") + cmd := buildCommands() + mapOutput(cmd, stdoutBuf, stderrBuf) + cmd.SetArgs([]string{"version"}) + err := cmd.Execute() + assert.NoError(err) + stdout, stderr, err := readCloseOutput(stdoutBuf, stderrBuf) + assert.NoError(err) + assert.Empty(stderr) + assert.NotEmpty(stdout) + fmt.Println(stdout) + assert.Equal("sidecars (devel)\n", stdout) +} + +func TestBasicAPI(t *testing.T) { + assert := assert.New(t) + cmd := buildCommands() + cmd.SetArgs([]string{"notexist", "test", "--help"}) + err := cmd.Execute() + assert.Error(err) + cmd = buildCommands() + cmd.SetArgs([]string{"cloner", "clone", "--help"}) + err = cmd.Execute() + assert.NoError(err) + cmd = buildCommands() + cmd.SetArgs([]string{"proxy", "serve", "--help"}) + err = cmd.Execute() + assert.NoError(err) +} diff --git a/config/crd/bases/amalthea.dev_amaltheasessions.yaml b/config/crd/bases/amalthea.dev_amaltheasessions.yaml index a0bc0693..324d62b6 100644 --- a/config/crd/bases/amalthea.dev_amaltheasessions.yaml +++ b/config/crd/bases/amalthea.dev_amaltheasessions.yaml @@ -5640,6 +5640,19 @@ spec: - image - port type: object + sidecars: + description: Control over the sidecars and init containers Amalthea + adds to each session + properties: + image: + description: |- + The docker image with the sidecars CLI. + The containers that are templated are decided based on the image version tag, falling back + on the latest templates for the latest version. Using a non-official image here is strongly + discouraged, if you must then you should use the same semver tags as the official image you + started with or based your custom image on. + type: string + type: object tolerations: description: |- If specified, the pod's tolerations. diff --git a/config/manifests/bases/amalthea.clusterserviceversion.yaml b/config/manifests/bases/amalthea.clusterserviceversion.yaml index d20b716e..b83af2f1 100644 --- a/config/manifests/bases/amalthea.clusterserviceversion.yaml +++ b/config/manifests/bases/amalthea.clusterserviceversion.yaml @@ -15,8 +15,9 @@ spec: kind: AmaltheaSession name: amaltheasessions.amalthea.dev statusDescriptors: - - description: Conditions store the status conditions of the AmaltheaSessions. - This is a standard thing that many operators implement see https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + - description: |- + Conditions store the status conditions of the AmaltheaSessions. This is a standard thing that + many operators implement see https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties displayName: Conditions path: conditions version: v1alpha1 diff --git a/config/samples/culling-configured.yaml b/config/samples/culling-configured.yaml index 3b0d5dde..421fdf89 100644 --- a/config/samples/culling-configured.yaml +++ b/config/samples/culling-configured.yaml @@ -15,3 +15,5 @@ spec: maxStartingDuration: 2m maxFailedDuration: 5m maxHibernatedDuration: 30s + sidecars: + image: renku/sidecars:0.0.1 diff --git a/controller/crds/amaltheasession.yaml b/controller/crds/amaltheasession.yaml deleted file mode 100644 index 480c1a9b..00000000 --- a/controller/crds/amaltheasession.yaml +++ /dev/null @@ -1,302 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: amaltheasessions.amalthea.dev -spec: - scope: Namespaced - group: amalthea.dev - names: - plural: amaltheasessions - singular: amaltheasession - kind: AlmaltheaSession - shortNames: - - asn - - versions: - - name: v1alpha1 - served: true - storage: true - additionalPrinterColumns: - - jsonPath: .status.phase - description: The current session startup phase - name: Phase - type: string - subresources: - status: {} - - schema: - openAPIV3Schema: - type: object - description: AmaltheaSession is the Schema for the session API - properties: - spec: - type: object - description: User defined specification for an Amalthea Session custom resource. - properties: - codeRepositories: - type: array - description: Code that will be pulled into the session - items: - type: object - properties: - clonePath: - type: string - description: Path relative to the root of the work folder to where - the repository should be cloned into. - git: - type: object - description: Project's git source - properties: - remote: - type: string - description: The remote name. - revision: - type: string - description: The revision to be checkout from. This can - be a branch, tag or commit id. - container: - type: object - description: session container specification - properties: - args: - type: array - description: Arguments passed to the command of the image or the - overridden command below. - items: - type: string - command: - type: array - description: Command to run in place of the image provided - command. - items: - type: string - env: - type: array - description: Environment variables used in this container - items: - type: object - properties: - name: - type: string - value: - type: string - required: - - name - - value - image: - type: string - resources: - type: object - default: {} - description: >- - Pod resources request - example: - requests: - memory: "64Mi" - cpu: "250m" - limits: - memory: "128Mi" - cpu: "500m" - name: - type: string - required: - - name - - extraContainers: - type: array - default: [] - description: Extra containers to run alongside the main container - items: - type: object - properties: - args: - type: array - description: Arguments passed to the command of the image or the - overridden command below. - items: - type: string - command: - type: array - description: Command to run in place of the image provided - command. - items: - type: string - env: - type: array - description: Environment variables used in this container - items: - type: object - properties: - name: - type: string - value: - type: string - required: - - name - - value - image: - type: string - resources: - type: object - default: {} - description: >- - Pod resources request - example: - requests: - memory: "64Mi" - cpu: "250m" - limits: - memory: "128Mi" - cpu: "500m" - name: - type: string - required: - - name - - image - - initContainers: - type: array - default: [] - description: Init containers that run before the rest - items: - type: object - properties: - args: - type: array - description: Arguments passed to the command of the image or the - overridden command below. - items: - type: string - command: - type: array - description: Command to run in place of the image provided - command. - items: - type: string - env: - type: array - description: Environment variables used in this container - items: - type: object - properties: - name: - type: string - value: - type: string - required: - - name - - value - image: - type: string - resources: - type: object - default: {} - description: >- - Pod resources request - example: - requests: - memory: "64Mi" - cpu: "250m" - limits: - memory: "128Mi" - cpu: "500m" - required: - - name - - image - - dataSources: - type: array - default: [] - description: List of data source to connect to and mount in the main - container. - items: - type: object - properties: - remote: - type: string - description: URL of the data source to connect to - mountPath: - type: string - description: Path to were the data source should be mounted - secret: - type: string - description: Name of the secret containing the credentials for the - data source. - required: - - remote - - mountPath - - culling: - type: object - default: {} - description: Options about culling idle servers - properties: - maxAgeSecondsThreshold: - type: integer - default: 0 - minimum: 0 - description: - The maximum allowed age for a session, regardless of whether it - is active or not. When the threshold is reached the session is hibernated. - A value of zero indicates that Amalthea will not automatically hibernate - the session based on its age. - idleSecondsThreshold: - type: integer - minimum: 0 - default: 0 - description: - How long should a server be idle for before it is hibernated. A value of - zero indicates that Amalthea will not automatically hibernate inactive sessions. - startingSecondsThreshold: - type: integer - default: 0 - minimum: 0 - description: - How long can a server be in starting state before it gets hibernated. A - value of zero indicates that the server will not be automatically hibernated - by Amalthea because it took to long to start. - failedSecondsThreshold: - type: integer - default: 0 - minimum: 0 - description: - How long can a server be in failed state before it gets hibernated. A - value of zero indicates that the server will not be automatically - hibernated by Amalthea if it is failing. - hibernatedSecondsThreshold: - type: integer - default: 0 - minimum: 0 - description: - Number of seconds where a server can be in hibernated state before - it gets completely deleted. A value of zero indicates that hibernated servers - will not be automatically be deleted by Amalthea after a period of time. - authentication: - type: object - default: {} - description: OIDC configuration - properties: - enabled: - type: boolean - default: false - description: Whether OIDC is enabled for this environement - configuration: - type: object - description: Authentication configuration options - oneOf: - - required: - - token - - required: - - oidc - properties: - token: - type: string - description: A pre-generated token that can be used to authenticate a - user. - configuration: - type: object - description: Configuration to be applied - properties: - secretRef: - type: string - description: Name of the secret containing the OIDC configuration diff --git a/go.mod b/go.mod index 6f3c12a1..ca8c96b8 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,22 @@ module github.com/SwissDataScienceCenter/amalthea -go 1.21 +go 1.21.0 + +toolchain go1.21.11 require ( + github.com/Masterminds/semver/v3 v3.3.0 + github.com/containers/image/v5 v5.32.2 + github.com/go-git/go-git/v5 v5.12.0 + github.com/labstack/echo/v4 v4.12.0 + github.com/labstack/gommon v0.4.2 github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/gomega v1.27.10 + github.com/spf13/cobra v1.8.1 + github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.19.0 + github.com/stretchr/testify v1.9.0 + gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.28.3 k8s.io/apimachinery v0.28.3 k8s.io/client-go v0.28.3 @@ -14,56 +26,88 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/containers/storage v1.55.0 // indirect + github.com/cyphar/filepath-securejoin v0.3.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/zapr v1.2.4 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.6 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.51.1 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.25.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.9.3 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.22.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.28.3 // indirect k8s.io/component-base v0.28.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect diff --git a/go.sum b/go.sum index 2ab8e1ea..22294dbb 100644 --- a/go.sum +++ b/go.sum @@ -1,81 +1,138 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/containers/image/v5 v5.32.2 h1:SzNE2Y6sf9b1GJoC8qjCuMBXwQrACFp4p0RK15+4gmQ= +github.com/containers/image/v5 v5.32.2/go.mod h1:v1l73VeMugfj/QtKI+jhYbwnwFCFnNGckvbST3rQ5Hk= +github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg= +github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cyphar/filepath-securejoin v0.3.1 h1:1V7cHiaW+C+39wEfpH6XlLBQo3j/PciWFrgfCLS8XrE= +github.com/cyphar/filepath-securejoin v0.3.1/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +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= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 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/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 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/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= +github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +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/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -87,37 +144,76 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw= +github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= 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= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= @@ -131,76 +227,111 @@ go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= 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/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 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/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 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.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 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.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= 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= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/helm-chart/amalthea-sessions/templates/amaltheasession-crd.yaml b/helm-chart/amalthea-sessions/templates/amaltheasession-crd.yaml index 2960c9c9..d4b5b085 100644 --- a/helm-chart/amalthea-sessions/templates/amaltheasession-crd.yaml +++ b/helm-chart/amalthea-sessions/templates/amaltheasession-crd.yaml @@ -1,12 +1,12 @@ {{- if .Values.deployCrd -}} +# This manifest is auto-generated from the makefile do not edit manually. +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - name: amaltheasessions.amalthea.dev annotations: controller-gen.kubebuilder.io/version: v0.15.0 - labels: - {{- include "amalthea-sessions.labels" . | nindent 4 }} + name: amaltheasessions.amalthea.dev spec: group: amalthea.dev names: @@ -64,6 +64,770 @@ spec: spec: description: AmaltheaSessionSpec defines the desired state of AmaltheaSession properties: + affinity: + description: |- + If specified, the pod's scheduling constraints + Passed right through to the Statefulset used for the session. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object authentication: description: Authentication configuration for the session properties: @@ -125,8 +889,8 @@ spec: properties: adopt: description: If the secret is adopted then the operator will - delete the secret when the custom resource that uses it is - deleted. + delete the secret when the custom resource that uses it + is deleted. type: boolean key: type: string @@ -152,8 +916,8 @@ spec: properties: clonePath: default: . - description: Path relative to the session working directory where - the repository should be cloned into. + description: Path relative to the session working directory + where the repository should be cloned into. example: repositories/project1 type: string cloningConfigSecretRef: @@ -166,9 +930,9 @@ spec: NOTE: you have to specify the whole config in a single key in the secret. properties: adopt: - description: If the secret is adopted then the operator will - delete the secret when the custom resource that uses it - is deleted. + description: If the secret is adopted then the operator + will delete the secret when the custom resource that uses + it is deleted. type: boolean key: type: string @@ -185,9 +949,9 @@ spec: NOTE: you have to specify the whole config in a single key in the secret. properties: adopt: - description: If the secret is adopted then the operator will - delete the secret when the custom resource that uses it - is deleted. + description: If the secret is adopted then the operator + will delete the secret when the custom resource that uses + it is deleted. type: boolean key: type: string @@ -208,8 +972,8 @@ spec: type: string type: default: git - description: The type of the code repository - currently the only - supported kind is git. + description: The type of the code repository - currently the + only supported kind is git. enum: - git type: string @@ -279,8 +1043,8 @@ spec: type: string mountPath: default: data - description: Path relative to the session working directory where - the data should be mounted + description: Path relative to the session working directory + where the data should be mounted example: data/storages type: string secretRef: @@ -291,9 +1055,9 @@ spec: rclone: any valid rclone configuration for a single remote, see the output of `rclone config providers` for validation and format. properties: adopt: - description: If the secret is adopted then the operator will - delete the secret when the custom resource that uses it - is deleted. + description: If the secret is adopted then the operator + will delete the secret when the custom resource that uses + it is deleted. type: boolean name: type: string @@ -313,8 +1077,8 @@ spec: Additional containers to add to the session statefulset. NOTE: The container names provided will be partially overwritten and randomized to avoid collisions items: - description: A single application container that you want to run within - a pod. + description: A single application container that you want to run + within a pod. properties: args: description: |- @@ -351,8 +1115,8 @@ spec: in a Container. properties: name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. + description: Name of the environment variable. Must be + a C_IDENTIFIER. type: string value: description: |- @@ -383,8 +1147,8 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: - description: Specify whether the ConfigMap or its - key must be defined + description: Specify whether the ConfigMap or + its key must be defined type: boolean required: - key @@ -446,8 +1210,8 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: - description: Specify whether the Secret or its key - must be defined + description: Specify whether the Secret or its + key must be defined type: boolean required: - key @@ -467,8 +1231,8 @@ spec: Values defined by an Env with a duplicate key will take precedence. Cannot be updated. items: - description: EnvFromSource represents the source of a set of - ConfigMaps + description: EnvFromSource represents the source of a set + of ConfigMaps properties: configMapRef: description: The ConfigMap to select from @@ -480,13 +1244,14 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: - description: Specify whether the ConfigMap must be defined + description: Specify whether the ConfigMap must be + defined type: boolean type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each key - in the ConfigMap. Must be a C_IDENTIFIER. + description: An optional identifier to prepend to each + key in the ConfigMap. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -600,8 +1365,8 @@ spec: lifecycle hooks will fail in runtime when tcp handler is specified. properties: host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' + description: 'Optional: Host name to connect to, + defaults to the pod IP.' type: string port: anyOf: @@ -697,8 +1462,8 @@ spec: lifecycle hooks will fail in runtime when tcp handler is specified. properties: host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' + description: 'Optional: Host name to connect to, + defaults to the pod IP.' type: string port: anyOf: @@ -745,16 +1510,16 @@ spec: description: GRPC specifies an action involving a GRPC port. properties: port: - description: Port number of the gRPC service. Number must - be in the range 1 to 65535. + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. format: int32 type: integer service: description: |- Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - + + If this is not specified, the default behavior is defined by gRPC. type: string required: @@ -772,8 +1537,8 @@ spec: description: Custom headers to set in the request. HTTP allows repeated headers. items: - description: HTTPHeader describes a custom header to - be used in HTTP probes + description: HTTPHeader describes a custom header + to be used in HTTP probes properties: name: description: |- @@ -884,8 +1649,8 @@ spec: For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. items: - description: ContainerPort represents a network port in a single - container. + description: ContainerPort represents a network port in a + single container. properties: containerPort: description: |- @@ -955,16 +1720,16 @@ spec: description: GRPC specifies an action involving a GRPC port. properties: port: - description: Port number of the gRPC service. Number must - be in the range 1 to 65535. + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. format: int32 type: integer service: description: |- Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - + + If this is not specified, the default behavior is defined by gRPC. type: string required: @@ -982,8 +1747,8 @@ spec: description: Custom headers to set in the request. HTTP allows repeated headers. items: - description: HTTPHeader describes a custom header to - be used in HTTP probes + description: HTTPHeader describes a custom header + to be used in HTTP probes properties: name: description: |- @@ -1110,12 +1875,12 @@ spec: description: |- Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - - + + This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. - - + + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. @@ -1304,8 +2069,8 @@ spec: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - - + + Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -1380,16 +2145,16 @@ spec: description: GRPC specifies an action involving a GRPC port. properties: port: - description: Port number of the gRPC service. Number must - be in the range 1 to 65535. + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. format: int32 type: integer service: description: |- Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - + + If this is not specified, the default behavior is defined by gRPC. type: string required: @@ -1407,8 +2172,8 @@ spec: description: Custom headers to set in the request. HTTP allows repeated headers. items: - description: HTTPHeader describes a custom header to - be used in HTTP probes + description: HTTPHeader describes a custom header + to be used in HTTP probes properties: name: description: |- @@ -1569,8 +2334,8 @@ spec: Pod volumes to mount into the container's filesystem. Cannot be updated. items: - description: VolumeMount describes a mounting of a Volume within - a container. + description: VolumeMount describes a mounting of a Volume + within a container. properties: mountPath: description: |- @@ -1621,11 +2386,11 @@ spec: type: object type: array extraVolumes: - description: Additional volumes to include in the statefulset for a - session + description: Additional volumes to include in the statefulset for + a session items: - description: Volume represents a named volume in a pod that may be - accessed by any container in the pod. + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. properties: awsElasticBlockStore: description: |- @@ -1675,7 +2440,8 @@ spec: blob storage type: string diskURI: - description: diskURI is the URI of data disk in the blob storage + description: diskURI is the URI of data disk in the blob + storage type: string fsType: description: |- @@ -1684,10 +2450,10 @@ spec: Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. type: string kind: - description: 'kind expected values are Shared: multiple blob - disks per storage account Dedicated: single blob disk per - storage account Managed: azure managed data disk (only - in managed availability set). defaults to shared' + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' type: string readOnly: description: |- @@ -1939,7 +2705,8 @@ spec: properties: fieldRef: description: 'Required: Selects a field of the pod: - only annotations, labels, name and namespace are supported.' + only annotations, labels, name and namespace are + supported.' properties: apiVersion: description: Version of the schema the FieldPath @@ -1964,11 +2731,11 @@ spec: format: int32 type: integer path: - description: 'Required: Path is the relative path name - of the file to be created. Must not be absolute or - contain the ''..'' path. Must be utf-8 encoded. The - first item of the relative path must not start with - ''..''' + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' type: string resourceFieldRef: description: |- @@ -2030,8 +2797,8 @@ spec: ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. - - + + Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity @@ -2041,18 +2808,18 @@ spec: a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). - - + + Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. - - + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. - - + + A pod can use both types of ephemeral volumes and persistent volumes at the same time. properties: @@ -2065,8 +2832,8 @@ spec: `` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). - - + + An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until @@ -2075,12 +2842,12 @@ spec: owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. - - + + This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. - - + + Required, must not be nil. properties: metadata: @@ -2195,16 +2962,16 @@ spec: description: |- Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - - + + This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. - - + + This field is immutable. It can only be set for containers. items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. + description: ResourceClaim references one + entry in PodSpec.ResourceClaims. properties: name: description: |- @@ -2258,8 +3025,8 @@ spec: relates the key and values. properties: key: - description: key is the label key that the - selector applies to. + description: key is the label key that + the selector applies to. type: string operator: description: |- @@ -2301,8 +3068,8 @@ spec: Value of Filesystem is implied when not included in claim spec. type: string volumeName: - description: volumeName is the binding reference to - the PersistentVolume backing this claim. + description: volumeName is the binding reference + to the PersistentVolume backing this claim. type: string type: object required: @@ -2310,8 +3077,9 @@ spec: type: object type: object fc: - description: fc represents a Fibre Channel resource that is attached - to a kubelet's host machine and then exposed to the pod. + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. properties: fsType: description: |- @@ -2349,8 +3117,8 @@ spec: provisioned/attached using an exec based plugin. properties: driver: - description: driver is the name of the driver to use for this - volume. + description: driver is the name of the driver to use for + this volume. type: string fsType: description: |- @@ -2389,8 +3157,8 @@ spec: - driver type: object flocker: - description: flocker represents a Flocker volume attached to a - kubelet's host machine. This depends on the Flocker control + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control service being running properties: datasetName: @@ -2760,18 +3528,18 @@ spec: file items: description: DownwardAPIVolumeFile represents - information to create the file containing the - pod field + information to create the file containing + the pod field properties: fieldRef: - description: 'Required: Selects a field of - the pod: only annotations, labels, name - and namespace are supported.' + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' properties: apiVersion: description: Version of the schema the - FieldPath is written in terms of, defaults - to "v1". + FieldPath is written in terms of, + defaults to "v1". type: string fieldPath: description: Path of the field to select @@ -2794,9 +3562,10 @@ spec: path: description: 'Required: Path is the relative path name of the file to be created. Must - not be absolute or contain the ''..'' path. - Must be utf-8 encoded. The first item of - the relative path must not start with ''..''' + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' type: string resourceFieldRef: description: |- @@ -2812,12 +3581,13 @@ spec: - type: integer - type: string description: Specifies the output format - of the exposed resources, defaults to - "1" + of the exposed resources, defaults + to "1" pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true resource: - description: 'Required: resource to select' + description: 'Required: resource to + select' type: string required: - resource @@ -2915,8 +3685,8 @@ spec: type: array type: object quobyte: - description: quobyte represents a Quobyte mount on the host that - shares a pod's lifetime + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime properties: group: description: |- @@ -3021,8 +3791,8 @@ spec: - monitors type: object scaleIO: - description: scaleIO represents a ScaleIO persistent volume attached - and mounted on Kubernetes nodes. + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. properties: fsType: description: |- @@ -3032,12 +3802,12 @@ spec: Default is "xfs". type: string gateway: - description: gateway is the host address of the ScaleIO API - Gateway. + description: gateway is the host address of the ScaleIO + API Gateway. type: string protectionDomain: - description: protectionDomain is the name of the ScaleIO Protection - Domain for the configured storage. + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. type: string readOnly: description: |- @@ -3071,8 +3841,8 @@ spec: with the protection domain. type: string system: - description: system is the name of the storage system as configured - in ScaleIO. + description: system is the name of the storage system as + configured in ScaleIO. type: string volumeName: description: |- @@ -3201,8 +3971,8 @@ spec: Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. type: string storagePolicyID: - description: storagePolicyID is the storage Policy Based Management - (SPBM) profile ID associated with the StoragePolicyName. + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. type: string storagePolicyName: description: storagePolicyName is the storage Policy Based @@ -3245,8 +4015,8 @@ spec: properties: adopt: description: If the secret is adopted then the operator will - delete the secret when the custom resource that uses it is - deleted. + delete the secret when the custom resource that uses it + is deleted. type: boolean name: type: string @@ -3261,8 +4031,8 @@ spec: Additional init containers to add to the session statefulset NOTE: The container names provided will be partially overwritten and randomized to avoid collisions items: - description: A single application container that you want to run within - a pod. + description: A single application container that you want to run + within a pod. properties: args: description: |- @@ -3299,8 +4069,8 @@ spec: in a Container. properties: name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. + description: Name of the environment variable. Must be + a C_IDENTIFIER. type: string value: description: |- @@ -3331,8 +4101,8 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: - description: Specify whether the ConfigMap or its - key must be defined + description: Specify whether the ConfigMap or + its key must be defined type: boolean required: - key @@ -3394,8 +4164,8 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: - description: Specify whether the Secret or its key - must be defined + description: Specify whether the Secret or its + key must be defined type: boolean required: - key @@ -3415,8 +4185,8 @@ spec: Values defined by an Env with a duplicate key will take precedence. Cannot be updated. items: - description: EnvFromSource represents the source of a set of - ConfigMaps + description: EnvFromSource represents the source of a set + of ConfigMaps properties: configMapRef: description: The ConfigMap to select from @@ -3428,13 +4198,14 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: - description: Specify whether the ConfigMap must be defined + description: Specify whether the ConfigMap must be + defined type: boolean type: object x-kubernetes-map-type: atomic prefix: - description: An optional identifier to prepend to each key - in the ConfigMap. Must be a C_IDENTIFIER. + description: An optional identifier to prepend to each + key in the ConfigMap. Must be a C_IDENTIFIER. type: string secretRef: description: The Secret to select from @@ -3548,8 +4319,8 @@ spec: lifecycle hooks will fail in runtime when tcp handler is specified. properties: host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' + description: 'Optional: Host name to connect to, + defaults to the pod IP.' type: string port: anyOf: @@ -3645,8 +4416,8 @@ spec: lifecycle hooks will fail in runtime when tcp handler is specified. properties: host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' + description: 'Optional: Host name to connect to, + defaults to the pod IP.' type: string port: anyOf: @@ -3693,16 +4464,16 @@ spec: description: GRPC specifies an action involving a GRPC port. properties: port: - description: Port number of the gRPC service. Number must - be in the range 1 to 65535. + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. format: int32 type: integer service: description: |- Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - + + If this is not specified, the default behavior is defined by gRPC. type: string required: @@ -3720,8 +4491,8 @@ spec: description: Custom headers to set in the request. HTTP allows repeated headers. items: - description: HTTPHeader describes a custom header to - be used in HTTP probes + description: HTTPHeader describes a custom header + to be used in HTTP probes properties: name: description: |- @@ -3832,8 +4603,8 @@ spec: For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. items: - description: ContainerPort represents a network port in a single - container. + description: ContainerPort represents a network port in a + single container. properties: containerPort: description: |- @@ -3903,16 +4674,16 @@ spec: description: GRPC specifies an action involving a GRPC port. properties: port: - description: Port number of the gRPC service. Number must - be in the range 1 to 65535. + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. format: int32 type: integer service: description: |- Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - + + If this is not specified, the default behavior is defined by gRPC. type: string required: @@ -3930,8 +4701,8 @@ spec: description: Custom headers to set in the request. HTTP allows repeated headers. items: - description: HTTPHeader describes a custom header to - be used in HTTP probes + description: HTTPHeader describes a custom header + to be used in HTTP probes properties: name: description: |- @@ -4058,12 +4829,12 @@ spec: description: |- Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - - + + This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. - - + + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. @@ -4252,8 +5023,8 @@ spec: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - - + + Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -4328,16 +5099,16 @@ spec: description: GRPC specifies an action involving a GRPC port. properties: port: - description: Port number of the gRPC service. Number must - be in the range 1 to 65535. + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. format: int32 type: integer service: description: |- Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - + + If this is not specified, the default behavior is defined by gRPC. type: string required: @@ -4355,8 +5126,8 @@ spec: description: Custom headers to set in the request. HTTP allows repeated headers. items: - description: HTTPHeader describes a custom header to - be used in HTTP probes + description: HTTPHeader describes a custom header + to be used in HTTP probes properties: name: description: |- @@ -4517,8 +5288,8 @@ spec: Pod volumes to mount into the container's filesystem. Cannot be updated. items: - description: VolumeMount describes a mounting of a Volume within - a container. + description: VolumeMount describes a mounting of a Volume + within a container. properties: mountPath: description: |- @@ -4568,13 +5339,21 @@ spec: - name type: object type: array + nodeSelector: + additionalProperties: + type: string + description: |- + Selector which must match a node's labels for the pod to be scheduled on that node. + Passed right through to the Statefulset used for the session. + type: object + x-kubernetes-map-type: atomic session: - description: Specification for the main session container that the user - will access and use + description: Specification for the main session container that the + user will access and use properties: args: - description: The arguments to run in the session container, if omitted - it will use the Docker image CMD + description: The arguments to run in the session container, if + omitted it will use the Docker image CMD items: type: string type: array @@ -4590,7 +5369,8 @@ spec: in a Container. properties: name: - description: Name of the environment variable. Must be a C_IDENTIFIER. + description: Name of the environment variable. Must be a + C_IDENTIFIER. type: string value: description: |- @@ -4634,12 +5414,12 @@ spec: spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. properties: apiVersion: - description: Version of the schema the FieldPath is - written in terms of, defaults to "v1". + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". type: string fieldPath: - description: Path of the field to select in the specified - API version. + description: Path of the field to select in the + specified API version. type: string required: - fieldPath @@ -4658,8 +5438,8 @@ spec: anyOf: - type: integer - type: string - description: Specifies the output format of the exposed - resources, defaults to "1" + description: Specifies the output format of the + exposed resources, defaults to "1" pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true resource: @@ -4670,7 +5450,8 @@ spec: type: object x-kubernetes-map-type: atomic secretKeyRef: - description: Selects a key of a secret in the pod's namespace + description: Selects a key of a secret in the pod's + namespace properties: key: description: The key of the secret to select from. Must @@ -4761,12 +5542,12 @@ spec: description: |- Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. - - + + This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. - - + + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. @@ -4813,7 +5594,7 @@ spec: default: 1000 description: |- The group is set on the session and this value is also set as the fsgroup for the whole pod and all session - contianers. + containers. format: int64 minimum: 0 type: integer @@ -4861,6 +5642,60 @@ spec: - image - port type: object + sidecars: + description: Control over the sidecars and init containers Amalthea + adds to each session + properties: + image: + description: |- + The docker image with the sidecars CLI. + The containers that are templated are decided based on the image version tag, falling back + on the latest templates for the latest version. Using a non-official image here is strongly + discouraged, if you must then you should use the same semver tags as the official image you + started with or based your custom image on. + type: string + type: object + tolerations: + description: |- + If specified, the pod's tolerations. + Passed right through to the Statefulset used for the session. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array required: - hibernated - session @@ -4938,10 +5773,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] -{{- end }} diff --git a/helm-chart/amalthea-sessions/values.yaml b/helm-chart/amalthea-sessions/values.yaml index 0b1d869d..7b78e485 100644 --- a/helm-chart/amalthea-sessions/values.yaml +++ b/helm-chart/amalthea-sessions/values.yaml @@ -30,4 +30,5 @@ deployCrd: true # This is the default class name from the csi-rclone Helm chart, if you use the defaults there # you can use the default here as well. The csi-rclone Helm chart https://github.com/SwissDataScienceCenter/csi-rclone # is needed in order to mount Rclone data sources in amalthea sessions. +# Changing the storage class name will result in the restart of all active amalthea sessions. rcloneStorageClass: csi-rclone-secret-annotation diff --git a/helm-chart/amalthea/templates/crd.yaml b/helm-chart/amalthea/templates/crd.yaml index 42349538..6773a729 100644 --- a/helm-chart/amalthea/templates/crd.yaml +++ b/helm-chart/amalthea/templates/crd.yaml @@ -1,5 +1,5 @@ {{- if .Values.deployCrd -}} -# This manifest is auto-generated from controller/crds/jupyter_server.yaml, do not modify. +# This manifest is auto-generated from the makefile do not edit manually. apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/helm-chart/amalthea/values.yaml b/helm-chart/amalthea/values.yaml index df08d588..8ef68d96 100644 --- a/helm-chart/amalthea/values.yaml +++ b/helm-chart/amalthea/values.yaml @@ -12,8 +12,7 @@ global: image: repository: renku/certificates tag: "0.0.2" - customCAs: - [] + customCAs: [] # - secret: # Inject some extra env variables directly from a config map envFromConfigMaps: [] @@ -81,8 +80,7 @@ kopf: # [statefulset, persistentvolumeclaims, services, ingresses, secrets, configmaps] # which are necessary for Amalthea to work, add the corresponding API groups and # resources here as an array of name/group objects, eg: -extraChildResources: - [] +extraChildResources: [] # - name: jupyterservers # group: amalthea.dev diff --git a/authproxy/cmd/root.go b/internal/authproxy/root.go similarity index 54% rename from authproxy/cmd/root.go rename to internal/authproxy/root.go index e3912a43..87211513 100644 --- a/authproxy/cmd/root.go +++ b/internal/authproxy/root.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package authproxy import ( "fmt" @@ -27,52 +27,37 @@ import ( const ConfigFlag = "config" -var ( - rootCmd = &cobra.Command{ - Use: "proxyauth", - Short: "A small authentication proxy", - Long: `authproxy is an reverse proxy that can be used -for token based authentication either through a cookie or -a header.`, - } -) +func initConfig(cmd *cobra.Command, args []string) { + aViper := viper.New() -func Execute() error { - return rootCmd.Execute() -} + aViper.SetEnvPrefix("authproxy") // will be uppercased automatically + aViper.AutomaticEnv() -func init() { - viper.SetEnvPrefix("authproxy") // will be uppercased automatically - viper.AutomaticEnv() + cmd.PersistentFlags().String(ConfigFlag, "", "config file (default is $HOME/.authproxy)") + err := viper.BindPFlag(ConfigFlag, cmd.PersistentFlags().Lookup(ConfigFlag)) + cobra.CheckErr(err) - rootCmd.PersistentFlags().String(ConfigFlag, "", "config file (default is $HOME/.authproxy)") - viper.BindPFlag(ConfigFlag, rootCmd.PersistentFlags().Lookup(ConfigFlag)) + cfgFile := aViper.GetString(ConfigFlag) - cobra.OnInitialize(initConfig) -} - -func initConfig() { - cfgFile := viper.GetString(ConfigFlag) - - viper.SetConfigType("yaml") + aViper.SetConfigType("yaml") if cfgFile != "" { // Use config file from the flag. - viper.SetConfigFile(cfgFile) + aViper.SetConfigFile(cfgFile) } else { // Find home directory. home, err := os.UserHomeDir() cobra.CheckErr(err) // Search config in home directory with name ".authproxy" (without extension). - viper.AddConfigPath(home) - viper.SetConfigName(".authproxy") + aViper.AddConfigPath(home) + aViper.SetConfigName(".authproxy") } - if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) + if err := aViper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", aViper.ConfigFileUsed()) } else { - if !rootCmd.Flags().Changed("config") { + if !cmd.Flags().Changed("config") { if _, isNotFound := err.(viper.ConfigFileNotFoundError); isNotFound { return } @@ -84,9 +69,12 @@ func initConfig() { // Workaround as mandatory flag error triggers when loaded from configuration // file or environment variable. // https://github.com/spf13/viper/issues/397#issuecomment-1304749092 - serveCmd.Flags().VisitAll(func(f *pflag.Flag) { - if viper.IsSet(f.Name) { - serveCmd.Flags().Set(f.Name, viper.GetString(f.Name)) + cmd.Flags().VisitAll(func(f *pflag.Flag) { + if aViper.IsSet(f.Name) { + err := cmd.Flags().Set(f.Name, aViper.GetString(f.Name)) + if err != nil { + cobra.CheckErr(err) + } } }) } diff --git a/authproxy/cmd/serve.go b/internal/authproxy/serve.go similarity index 67% rename from authproxy/cmd/serve.go rename to internal/authproxy/serve.go index 8f4b34e2..81693b56 100644 --- a/authproxy/cmd/serve.go +++ b/internal/authproxy/serve.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package authproxy import ( "fmt" @@ -29,7 +29,6 @@ import ( "github.com/labstack/gommon/log" ) - // The configuration options for the authentication proxy used for anonymous users. // The fields below can be passed as arguments i.e. --token=some-very-complicated-random-value // or as a yaml config file. @@ -39,36 +38,71 @@ const TokenFlag = "token" const CookieKeyFlag = "cookie_key" const VerboseFlag = "verbose" -func init() { - rootCmd.AddCommand(serveCmd) - +func Command() (*cobra.Command, error) { + var serveCmd = &cobra.Command{ + Use: "serve", + Short: "Run the proxy", + Run: serve, + PreRun: initConfig, + } serveCmd.PersistentFlags().String(RemoteFlag, "", "remote URL to proxy to") - serveCmd.MarkPersistentFlagRequired(RemoteFlag) - viper.BindPFlag(RemoteFlag, serveCmd.PersistentFlags().Lookup(RemoteFlag)) - viper.BindEnv(RemoteFlag) + err := serveCmd.MarkPersistentFlagRequired(RemoteFlag) + if err != nil { + return nil, err + } + err = viper.BindPFlag(RemoteFlag, serveCmd.PersistentFlags().Lookup(RemoteFlag)) + if err != nil { + return nil, err + } + err = viper.BindEnv(RemoteFlag) + if err != nil { + return nil, err + } serveCmd.PersistentFlags().Int(PortFlag, 65535, "port on which the proxy will listen") - viper.BindPFlag(PortFlag, serveCmd.PersistentFlags().Lookup(PortFlag)) - viper.BindEnv(PortFlag) + err = viper.BindPFlag(PortFlag, serveCmd.PersistentFlags().Lookup(PortFlag)) + if err != nil { + return nil, err + } + err = viper.BindEnv(PortFlag) + if err != nil { + return nil, err + } serveCmd.PersistentFlags().String(CookieKeyFlag, "renku-auth", "cookie key where to find the token") - viper.BindPFlag(CookieKeyFlag, serveCmd.PersistentFlags().Lookup(CookieKeyFlag)) - viper.BindEnv(CookieKeyFlag) + err = viper.BindPFlag(CookieKeyFlag, serveCmd.PersistentFlags().Lookup(CookieKeyFlag)) + if err != nil { + return nil, err + } + err = viper.BindEnv(CookieKeyFlag) + if err != nil { + return nil, err + } serveCmd.PersistentFlags().String(TokenFlag, "", "secret token for authentication") - serveCmd.MarkPersistentFlagRequired(TokenFlag) - viper.BindPFlag(TokenFlag, serveCmd.PersistentFlags().Lookup(TokenFlag)) - viper.BindEnv(TokenFlag) + err = serveCmd.MarkPersistentFlagRequired(TokenFlag) + if err != nil { + return nil, err + } + err = viper.BindPFlag(TokenFlag, serveCmd.PersistentFlags().Lookup(TokenFlag)) + if err != nil { + return nil, err + } + err = viper.BindEnv(TokenFlag) + if err != nil { + return nil, err + } serveCmd.PersistentFlags().Bool(VerboseFlag, false, "make the proxy verbose") - viper.BindPFlag(VerboseFlag, serveCmd.PersistentFlags().Lookup(VerboseFlag)) - viper.BindEnv(VerboseFlag) -} - -var serveCmd = &cobra.Command{ - Use: "serve", - Short: "Run the proxy", - Run: serve, + err = viper.BindPFlag(VerboseFlag, serveCmd.PersistentFlags().Lookup(VerboseFlag)) + if err != nil { + return nil, err + } + err = viper.BindEnv(VerboseFlag) + if err != nil { + return nil, err + } + return serveCmd, nil } func serve(cmd *cobra.Command, args []string) { @@ -110,7 +144,7 @@ func serve(cmd *cobra.Command, args []string) { return key == token, nil }, })) - + remoteURL, err := url.Parse(remoteURLStr) if err != nil { e.Logger.Fatal(err) diff --git a/cloner/cmd/clone.go b/internal/cloner/clone.go similarity index 86% rename from cloner/cmd/clone.go rename to internal/cloner/clone.go index 47e07947..2621a1f1 100644 --- a/cloner/cmd/clone.go +++ b/internal/cloner/clone.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cmd +package cloner import ( "errors" @@ -64,30 +64,6 @@ type CloneFonfig struct { Password string `yaml:"password"` } -func init() { - rootCmd.AddCommand(cloneCmd) - - cloneCmd.Flags().StringVar(&configPath, ConfigFlag, "", "Path to configuration file") - - cloneCmd.Flags().StringVar(&remote, RemoteFlag, "", "remote URL to proxy to") - cloneCmd.MarkFlagRequired(RemoteFlag) - - cloneCmd.Flags().StringVar(&revision, RevisionFlag, "", "remote revision (branch, tag, etc.)") - - cloneCmd.Flags().StringVar(&path, PathFlag, "", "clone path") - cloneCmd.MarkFlagRequired(PathFlag) - - cloneCmd.Flags().BoolVar(&verbose, VerboseFlag, false, "make the command verbose") - - cloneCmd.Flags().VarP(preCloningStrategy, StrategyFlag, "", "the pre cloning strategy") -} - -var cloneCmd = &cobra.Command{ - Use: "clone", - Short: "Clone the repository", - Run: clone, -} - func applyPreCloningStrategy(clonePath string) { if preCloningStrategy.Equal(NoStrategy) { log.Print("no strategy selected, let git handle the this.") diff --git a/cloner/cmd/enum_flag.go b/internal/cloner/enum_flag.go similarity index 98% rename from cloner/cmd/enum_flag.go rename to internal/cloner/enum_flag.go index de516b41..b9c2a499 100644 --- a/cloner/cmd/enum_flag.go +++ b/internal/cloner/enum_flag.go @@ -16,7 +16,7 @@ limitations under the License. // Based on: https://github.com/spf13/pflag/issues/236#issuecomment-931600452 -package cmd +package cloner import ( "fmt" diff --git a/internal/cloner/root.go b/internal/cloner/root.go new file mode 100644 index 00000000..7134f21d --- /dev/null +++ b/internal/cloner/root.go @@ -0,0 +1,51 @@ +/* +Copyright 2024. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cloner + +import ( + "github.com/spf13/cobra" +) + +func Command() (*cobra.Command, error) { + cmd := &cobra.Command{ + Use: "clone", + Short: "A small utility to clone repositories", + Long: `cloner is a helper to Amalthea to clone project related repositories`, + Run: clone, + } + preCloningStrategy := newEnum(PreCloningStrategies, NoStrategy) + cmd.Flags().StringVar(&configPath, ConfigFlag, "", "Path to configuration file") + + cmd.Flags().StringVar(&remote, RemoteFlag, "", "remote URL to proxy to") + err := cmd.MarkFlagRequired(RemoteFlag) + if err != nil { + return nil, err + } + + cmd.Flags().StringVar(&revision, RevisionFlag, "", "remote revision (branch, tag, etc.)") + + cmd.Flags().StringVar(&path, PathFlag, "", "clone path") + err = cmd.MarkFlagRequired(PathFlag) + if err != nil { + return nil, err + } + + cmd.Flags().BoolVar(&verbose, VerboseFlag, false, "make the command verbose") + + cmd.Flags().VarP(preCloningStrategy, StrategyFlag, "", "the pre cloning strategy") + return cmd, nil +} diff --git a/internal/controller/amaltheasession_controller.go b/internal/controller/amaltheasession_controller.go index dcc2cae5..8f5362c9 100644 --- a/internal/controller/amaltheasession_controller.go +++ b/internal/controller/amaltheasession_controller.go @@ -144,7 +144,18 @@ func (r *AmaltheaSessionReconciler) Reconcile(ctx context.Context, req ctrl.Requ log.Info("spec", "cr", amaltheasession) - children := NewChildResources(amaltheasession) + children, err := NewChildResources(amaltheasession) + if err != nil { + log.Error( + err, + "There was an error in generating the Kubernetes resources based on AmaltheaSession specification. Please report this with the Renku developers.", + "name", + amaltheasession.GetName(), + "namespace", + amaltheasession.GetNamespace(), + ) + return ctrl.Result{}, err + } updates, err := children.Reconcile(ctx, r.Client, amaltheasession) if err != nil { log.Error(err, "Failed when reconciling children") diff --git a/internal/controller/amaltheasession_controller_test.go b/internal/controller/amaltheasession_controller_test.go index 30b2115d..5df9eac8 100644 --- a/internal/controller/amaltheasession_controller_test.go +++ b/internal/controller/amaltheasession_controller_test.go @@ -72,6 +72,9 @@ var _ = Describe("AmaltheaSession Controller", func() { Ingress: &amaltheadevv1alpha1.Ingress{ Host: "test.com", }, + Sidecars: amaltheadevv1alpha1.Sidecars{ + Image: "renku/sidecars:0.0.1", + }, }, } Expect(k8sClient.Create(ctx, resource)).To(Succeed()) @@ -125,6 +128,9 @@ var _ = Describe("AmaltheaSession Controller", func() { Image: "debian:bookworm-slim", Port: 8000, }, + Sidecars: amaltheadevv1alpha1.Sidecars{ + Image: "renku/sidecars:0.0.1", + }, }, } Expect(k8sClient.Create(ctx, resource)).To(Succeed()) @@ -188,6 +194,9 @@ var _ = Describe("AmaltheaSession Controller", func() { Host: "test.com", TLSSecret: &amaltheadevv1alpha1.SessionSecretRef{Name: tlsSecretName}, }, + Sidecars: amaltheadevv1alpha1.Sidecars{ + Image: "renku/sidecars:0.0.1", + }, }, } @@ -259,6 +268,9 @@ var _ = Describe("AmaltheaSession Controller", func() { Image: "debian:bookworm-slim", Port: 8000, }, + Sidecars: amaltheadevv1alpha1.Sidecars{ + Image: "renku/sidecars:0.0.1", + }, }, } }) @@ -351,6 +363,9 @@ var _ = Describe("AmaltheaSession Controller", func() { Duration: 15 * time.Second, }, }, + Sidecars: amaltheadevv1alpha1.Sidecars{ + Image: "renku/sidecars:0.0.1", + }, }, } Expect(k8sClient.Create(ctx, resource)).To(Succeed()) diff --git a/internal/controller/children.go b/internal/controller/children.go index d0fce590..8dbed6d1 100644 --- a/internal/controller/children.go +++ b/internal/controller/children.go @@ -137,11 +137,14 @@ type ChildResourceUpdates struct { DataSourcesPVCs []ChildResourceUpdate[v1.PersistentVolumeClaim] } -func NewChildResources(cr *amaltheadevv1alpha1.AmaltheaSession) ChildResources { +func NewChildResources(cr *amaltheadevv1alpha1.AmaltheaSession) (ChildResources, error) { metadata := metav1.ObjectMeta{Name: cr.Name, Namespace: cr.Namespace} desiredService := cr.Service() desiredPVC := cr.PVC() - desiredStatefulSet := cr.StatefulSet() + desiredStatefulSet, err := cr.StatefulSet() + if err != nil { + return ChildResources{}, err + } desiredIngress := cr.Ingress() output := ChildResources{ Service: ChildResource[v1.Service]{&v1.Service{ObjectMeta: metadata}, &desiredService}, @@ -165,7 +168,7 @@ func NewChildResources(cr *amaltheadevv1alpha1.AmaltheaSession) ChildResources { } output.DataSourcesPVCs = desiredDataSourcesPVCs - return output + return output, nil } func (c ChildResources) Reconcile(ctx context.Context, clnt client.Client, cr *amaltheadevv1alpha1.AmaltheaSession) (ChildResourceUpdates, error) { diff --git a/internal/sidecartemplates/sidecartemplates.go b/internal/sidecartemplates/sidecartemplates.go new file mode 100644 index 00000000..f8e6dd07 --- /dev/null +++ b/internal/sidecartemplates/sidecartemplates.go @@ -0,0 +1,83 @@ +package sidecartemplates + +import ( + "fmt" + "log" + "slices" + + "github.com/Masterminds/semver/v3" + "github.com/containers/image/v5/docker/reference" +) + +type VersionedTemplates[S, T any] struct { + versions semver.Collection + templateFuncs map[semver.Version]TemplateFunc[S, T] +} + +// GetFunc extracts the version tag from the image, parses it as semver and then +// finds the closest matching template function for it. +func (v VersionedTemplates[S, T]) GetFunc(dockerImage string) (TemplateFunc[S, T], error) { + version, err := extractVersion(dockerImage) + if err != nil { + return nil, err + } + for _, minInclusiveVerion := range v.versions { + if version.GreaterThanEqual(minInclusiveVerion) { + return v.templateFuncs[*minInclusiveVerion], nil + } + } + if len(v.templateFuncs) == 0 { + log.Fatalln("there are no templates at all stored") + } + return nil, TemplateNotFoundErr +} + +// LatestFunc returns the template function for the latest (most recent) version +func (v VersionedTemplates[S, T]) LatestFunc() TemplateFunc[S, T] { + if len(v.templateFuncs) == 0 { + log.Fatalln("there are no templates at all stored") + } + return v.templateFuncs[*v.versions[0]] +} + +func extractVersion(image string) (*semver.Version, error) { + ref, err := reference.ParseNormalizedNamed(image) + if err != nil { + return nil, fmt.Errorf("cannot parse image") + } + ref = reference.TagNameOnly(ref) + tagged, ok := ref.(reference.NamedTagged) + if !ok { + return nil, fmt.Errorf("image does not containe a tag") + } + return semver.NewVersion(tagged.Tag()) +} + +type VersionedTemplate[S, T any] struct { + MinInclusiveVersion semver.Version + TemplateFunc TemplateFunc[S, T] +} + +func NewVersionedTemplates[S, T any](templates ...VersionedTemplate[S, T]) VersionedTemplates[S, T] { + if len(templates) == 0 { + log.Fatalln("cannot initialize a set of templates without any templates provided") + } + versions := semver.Collection{} + templateFuncs := map[semver.Version]TemplateFunc[S, T]{} + for i := range templates { + template := &templates[i] + versions = append(versions, &template.MinInclusiveVersion) + templateFuncs[template.MinInclusiveVersion] = template.TemplateFunc + } + slices.SortFunc(versions, func(a, b *semver.Version) int { + return b.Compare(a) + }) + return VersionedTemplates[S, T]{ + versions: versions, + templateFuncs: templateFuncs, + } +} + +var TemplateNotFoundErr = fmt.Errorf("the template could not be found") + +type TemplateFunc[S, T any] func(input *S) T diff --git a/internal/sidecartemplates/sidecartemplates_test.go b/internal/sidecartemplates/sidecartemplates_test.go new file mode 100644 index 00000000..97e45d17 --- /dev/null +++ b/internal/sidecartemplates/sidecartemplates_test.go @@ -0,0 +1,99 @@ +package sidecartemplates + +import ( + "testing" + + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type testResource struct { + name string +} +type testManifests struct { + name string +} + +// Note the test includes pre-releases but it is better to avoid these in real usage +// because sorting prerlease version can get tricky. +func makeNewTemplates() VersionedTemplates[testResource, testManifests] { + return NewVersionedTemplates( + VersionedTemplate[testResource, testManifests]{ + *semver.MustParse("v0.0.4"), + func(input *testResource) testManifests { + return testManifests{"v0.0.4"} + }, + }, + VersionedTemplate[testResource, testManifests]{ + *semver.MustParse("0.0.3-alpha"), + func(input *testResource) testManifests { + return testManifests{"0.0.3-alpha"} + }, + }, + VersionedTemplate[testResource, testManifests]{ + *semver.MustParse("0.0.3-aa1"), + func(input *testResource) testManifests { + return testManifests{"0.0.3-aa1"} + }, + }, + VersionedTemplate[testResource, testManifests]{ + *semver.MustParse("0.0.10-alpha.1"), + func(input *testResource) testManifests { + return testManifests{"0.0.10-alpha.1"} + }, + }, + VersionedTemplate[testResource, testManifests]{ + *semver.MustParse("0.0.10-beta"), + func(input *testResource) testManifests { + return testManifests{"0.0.10-beta"} + }, + }, + VersionedTemplate[testResource, testManifests]{ + *semver.MustParse("0.1.0"), + func(input *testResource) testManifests { + return testManifests{"0.1.0"} + }, + }, + VersionedTemplate[testResource, testManifests]{ + *semver.MustParse("0.1.0-beta"), + func(input *testResource) testManifests { + return testManifests{"0.1.0-beta"} + }, + }, + ) +} + +func TestGetFunc(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + templs := makeNewTemplates() + // You cannot get a template for an image whose semver is older than the oldest versioned template + _, err := templs.GetFunc("renku/sidecars:0.0.1") + assert.ErrorIs(err, TemplateNotFoundErr) + // The returned image should have a semver older or equal to the requested + f, err := templs.GetFunc("renku/sidecars:0.0.5") + require.NoError(err) + res := f(&testResource{}) + assert.Equal("v0.0.4", res.name) + // Alpha versions are properly sorted + f, err = templs.GetFunc("renku/sidecars:0.0.3") + require.NoError(err) + res = f(&testResource{}) + assert.Equal("0.0.3-alpha", res.name) + // Asking for a version that is newer than anything stored should return the newest + f, err = templs.GetFunc("renku/sidecars:0.4.0") + require.NoError(err) + res = f(&testResource{}) + assert.Equal("0.1.0", res.name) + // Changing the image name does not matter - just the semver matters + f, err = templs.GetFunc("image:0.4.0") + require.NoError(err) + res = f(&testResource{}) + assert.Equal("0.1.0", res.name) + // Ensure that prerelease versions are sorted correctly + f, err = templs.GetFunc("image:0.0.10") + require.NoError(err) + res = f(&testResource{}) + assert.Equal("0.0.10-beta", res.name) +} diff --git a/sidecars.Dockerfile b/sidecars.Dockerfile new file mode 100644 index 00000000..45a6cc4c --- /dev/null +++ b/sidecars.Dockerfile @@ -0,0 +1,33 @@ +# Build the binary +FROM golang:1.21 AS builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY cmd/ cmd/ +COPY api/ api/ +COPY internal/ internal/ + +# Build +# the GOARCH has not a default value to allow the binary be built according to the host where the command +# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO +# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, +# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o sidecars cmd/sidecars/main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/sidecars . +USER 65532:65532 + +ENTRYPOINT ["/sidecars"]