diff --git a/docs/usage/registry-cache/configuration.md b/docs/usage/registry-cache/configuration.md index 458adac9..5bc3d08c 100644 --- a/docs/usage/registry-cache/configuration.md +++ b/docs/usage/registry-cache/configuration.md @@ -92,6 +92,15 @@ The `providerConfig.caches[].garbageCollection.ttl` field is the time to live of The `providerConfig.caches[].secretReferenceName` is the name of the reference for the Secret containing the upstream registry credentials. To cache images from a private registry, credentials to the upstream registry should be supplied. For more details, see [How to provide credentials for upstream registry](upstream-credentials.md#how-to-provide-credentials-for-upstream-registry). +The `providerConfig.caches[].proxy.httpProxy` field contains settings for a proxy which is used by the registry cache. +The registry-cache extension sets this value as `HTTP_PROXY` ENV in the StatefulSet. + +The `providerConfig.caches[].proxy.httpsProxy` field contains settings for a proxy which is used by the registry cache. +The registry-cache extension sets this value as `HTTPS_PROXY` ENV in the StatefulSet. + +The `providerConfig.caches[].proxy.noProxy` field contains settings for a proxy which is used by the registry cache. +The registry-cache extension sets this value as `NO_PROXY` ENV in the StatefulSet. + > **Note**: It is only possible to provide one set of credentials for one private upstream registry. ## Garbage Collection diff --git a/pkg/apis/registry/types.go b/pkg/apis/registry/types.go index d469db59..5a285afa 100644 --- a/pkg/apis/registry/types.go +++ b/pkg/apis/registry/types.go @@ -38,6 +38,8 @@ type RegistryCache struct { GarbageCollection *GarbageCollection // SecretReferenceName is the name of the reference for the Secret containing the upstream registry credentials SecretReferenceName *string + // Proxy contains settings for a proxy used in the registry cache. + Proxy *Proxy } // Volume contains settings for the registry cache volume. @@ -58,6 +60,16 @@ type GarbageCollection struct { TTL metav1.Duration } +// Proxy contains settings for a proxy used in the registry cache. +type Proxy struct { + // HTTPProxy is used as HTTP_PROXY env in the StatefulSet. + HTTPProxy *string + // HTTPSProxy is used as HTTPS_PROXY env in the StatefulSet. + HTTPSProxy *string + // NoProxy is used as NO_PROXY env in the StatefulSet. + NoProxy *string +} + var ( // DefaultTTL is the default time to live of a blob in the cache. DefaultTTL = metav1.Duration{Duration: 7 * 24 * time.Hour} diff --git a/pkg/apis/registry/v1alpha3/types.go b/pkg/apis/registry/v1alpha3/types.go index 74792cef..6fd49761 100644 --- a/pkg/apis/registry/v1alpha3/types.go +++ b/pkg/apis/registry/v1alpha3/types.go @@ -43,6 +43,9 @@ type RegistryCache struct { // SecretReferenceName is the name of the reference for the Secret containing the upstream registry credentials. // +optional SecretReferenceName *string `json:"secretReferenceName,omitempty"` + // Proxy contains settings for a proxy used in the registry cache. + // +optional + Proxy *Proxy `json:"proxy,omitempty"` } // Volume contains settings for the registry cache volume. @@ -66,6 +69,19 @@ type GarbageCollection struct { TTL metav1.Duration `json:"ttl"` } +// Proxy contains settings for a proxy used in the registry cache. +type Proxy struct { + // HTTPProxy is used as HTTP_PROXY env in the StatefulSet. + // +optional + HTTPProxy *string `json:"httpProxy"` + // HTTPSProxy is used as HTTPS_PROXY env in the StatefulSet. + // +optional + HTTPSProxy *string `json:"httpsProxy"` + // NoProxy is used as NO_PROXY env in the StatefulSet. + // +optional + NoProxy *string `json:"noProxy"` +} + var ( // DefaultTTL is the default time to live of a blob in the cache. DefaultTTL = metav1.Duration{Duration: 7 * 24 * time.Hour} diff --git a/pkg/component/registrycaches/registry_caches.go b/pkg/component/registrycaches/registry_caches.go index e85dd498..05fa0ab6 100644 --- a/pkg/component/registrycaches/registry_caches.go +++ b/pkg/component/registrycaches/registry_caches.go @@ -380,6 +380,27 @@ func (r *registryCaches) computeResourcesDataForRegistryCache(ctx context.Contex }, } + if cache.Proxy != nil { + if cache.Proxy.HTTPProxy != nil { + statefulSet.Spec.Template.Spec.Containers[0].Env = append(statefulSet.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ + Name: "HTTP_PROXY", + Value: *cache.Proxy.HTTPProxy, + }) + } + if cache.Proxy.HTTPSProxy != nil { + statefulSet.Spec.Template.Spec.Containers[0].Env = append(statefulSet.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ + Name: "HTTPS_PROXY", + Value: *cache.Proxy.HTTPSProxy, + }) + } + if cache.Proxy.NoProxy != nil { + statefulSet.Spec.Template.Spec.Containers[0].Env = append(statefulSet.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ + Name: "NO_PROXY", + Value: *cache.Proxy.NoProxy, + }) + } + } + var vpa *vpaautoscalingv1.VerticalPodAutoscaler if r.values.VPAEnabled { updateMode := vpaautoscalingv1.UpdateModeAuto diff --git a/pkg/component/registrycaches/registry_caches_test.go b/pkg/component/registrycaches/registry_caches_test.go index ff71a01a..4125ef2f 100644 --- a/pkg/component/registrycaches/registry_caches_test.go +++ b/pkg/component/registrycaches/registry_caches_test.go @@ -198,7 +198,7 @@ status: ` } - statefulSetYAMLFor = func(name, upstream, size, configSecretName string, storageClassName *string) string { + statefulSetYAMLFor = func(name, upstream, size, configSecretName string, storageClassName *string, additionalEnvs []corev1.EnvVar) string { out := `apiVersion: apps/v1 kind: StatefulSet metadata: @@ -228,7 +228,14 @@ spec: containers: - env: - name: OTEL_TRACES_EXPORTER - value: none + value: none` + for i := range additionalEnvs { + _ = i + out += ` + - name: ` + additionalEnvs[i].Name + ` + value: ` + additionalEnvs[i].Value + } + out += ` image: ` + image + ` imagePullPolicy: IfNotPresent livenessProbe: @@ -379,11 +386,11 @@ status: {} expectedManifests := []string{ configSecretYAMLFor(dockerConfigSecretName, "registry-docker-io", "docker.io", configYAMLFor("https://registry-1.docker.io", "336h0m0s", "", "")), serviceYAMLFor("registry-docker-io", "docker.io", "https://registry-1.docker.io"), - statefulSetYAMLFor("registry-docker-io", "docker.io", "10Gi", dockerConfigSecretName, nil), + statefulSetYAMLFor("registry-docker-io", "docker.io", "10Gi", dockerConfigSecretName, nil, nil), vpaYAMLFor("registry-docker-io"), configSecretYAMLFor(arConfigSecretName, "registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", configYAMLFor("https://europe-docker.pkg.dev", "0s", "", "")), serviceYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "https://europe-docker.pkg.dev"), - statefulSetYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "20Gi", arConfigSecretName, ptr.To("premium")), + statefulSetYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "20Gi", arConfigSecretName, ptr.To("premium"), nil), vpaYAMLFor("registry-europe-docker-pkg-dev"), } Expect(manifests).To(ConsistOf(expectedManifests)) @@ -411,10 +418,65 @@ status: {} expectedManifests := []string{ configSecretYAMLFor(dockerConfigSecretName, "registry-docker-io", "docker.io", configYAMLFor("https://registry-1.docker.io", "336h0m0s", "", "")), serviceYAMLFor("registry-docker-io", "docker.io", "https://registry-1.docker.io"), - statefulSetYAMLFor("registry-docker-io", "docker.io", "10Gi", dockerConfigSecretName, nil), + statefulSetYAMLFor("registry-docker-io", "docker.io", "10Gi", dockerConfigSecretName, nil, nil), + configSecretYAMLFor(arConfigSecretName, "registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", configYAMLFor("https://europe-docker.pkg.dev", "0s", "", "")), + serviceYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "https://europe-docker.pkg.dev"), + statefulSetYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "20Gi", arConfigSecretName, ptr.To("premium"), nil), + } + Expect(manifests).To(ConsistOf(expectedManifests)) + }) + }) + + Context("when a proxy is set", func() { + BeforeEach(func() { + values.Caches[0].Proxy = &api.Proxy{ + HTTPProxy: ptr.To("http://127.0.0.1"), + HTTPSProxy: ptr.To("http://127.0.0.1"), + NoProxy: ptr.To("localhost"), + } + values.Caches[1].Proxy = &api.Proxy{ + HTTPProxy: ptr.To("http://127.0.0.1"), + HTTPSProxy: ptr.To("http://127.0.0.1"), + NoProxy: ptr.To("localhost"), + } + }) + + It("should successfully deploy the resources", func() { + Expect(registryCaches.Deploy(ctx)).To(Succeed()) + + Expect(c.Get(ctx, client.ObjectKeyFromObject(managedResource), managedResource)).To(Succeed()) + managedResourceSecret.Name = managedResource.Spec.SecretRefs[0].Name + Expect(c.Get(ctx, client.ObjectKeyFromObject(managedResourceSecret), managedResourceSecret)).To(Succeed()) + + manifests, err := test.ExtractManifestsFromManagedResourceData(managedResourceSecret.Data) + Expect(err).NotTo(HaveOccurred()) + Expect(manifests).To(HaveLen(8)) + + dockerConfigSecretName := "registry-docker-io-config-2935d46f" + arConfigSecretName := "registry-europe-docker-pkg-dev-config-245e2638" + additionalEnvs := []corev1.EnvVar{ + { + Name: "HTTP_PROXY", + Value: "http://127.0.0.1", + }, + { + Name: "HTTPS_PROXY", + Value: "http://127.0.0.1", + }, + { + Name: "NO_PROXY", + Value: "localhost", + }, + } + expectedManifests := []string{ + configSecretYAMLFor(dockerConfigSecretName, "registry-docker-io", "docker.io", configYAMLFor("https://registry-1.docker.io", "336h0m0s", "", "")), + serviceYAMLFor("registry-docker-io", "docker.io", "https://registry-1.docker.io"), + statefulSetYAMLFor("registry-docker-io", "docker.io", "10Gi", dockerConfigSecretName, nil, additionalEnvs), + vpaYAMLFor("registry-docker-io"), configSecretYAMLFor(arConfigSecretName, "registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", configYAMLFor("https://europe-docker.pkg.dev", "0s", "", "")), serviceYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "https://europe-docker.pkg.dev"), - statefulSetYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "20Gi", arConfigSecretName, ptr.To("premium")), + statefulSetYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "20Gi", arConfigSecretName, ptr.To("premium"), additionalEnvs), + vpaYAMLFor("registry-europe-docker-pkg-dev"), } Expect(manifests).To(ConsistOf(expectedManifests)) }) @@ -480,11 +542,11 @@ status: {} expectedManifests := []string{ configSecretYAMLFor(dockerConfigSecretName, "registry-docker-io", "docker.io", configYAMLFor("https://registry-1.docker.io", "336h0m0s", "docker-user", "s3cret")), serviceYAMLFor("registry-docker-io", "docker.io", "https://registry-1.docker.io"), - statefulSetYAMLFor("registry-docker-io", "docker.io", "10Gi", dockerConfigSecretName, nil), + statefulSetYAMLFor("registry-docker-io", "docker.io", "10Gi", dockerConfigSecretName, nil, nil), vpaYAMLFor("registry-docker-io"), configSecretYAMLFor(arConfigSecretName, "registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", configYAMLFor("https://europe-docker.pkg.dev", "0s", "ar-user", `{"foo":"bar"}`)), serviceYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "https://europe-docker.pkg.dev"), - statefulSetYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "20Gi", arConfigSecretName, ptr.To("premium")), + statefulSetYAMLFor("registry-europe-docker-pkg-dev", "europe-docker.pkg.dev", "20Gi", arConfigSecretName, ptr.To("premium"), nil), vpaYAMLFor("registry-europe-docker-pkg-dev"), } Expect(manifests).To(ConsistOf(expectedManifests))