Skip to content

Commit

Permalink
Add support for namespace overrides in image pulling
Browse files Browse the repository at this point in the history
  • Loading branch information
burmanm committed Sep 23, 2024
1 parent 5c7c2b6 commit 2b79709
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Changelog for Cass Operator, new PRs should update the `main / unreleased` secti

* [FEATURE] [#651](https://github.com/k8ssandra/cass-operator/issues/651) Add tsreload task for DSE deployments and ability to check if sync operation is available on the mgmt-api side
* [ENHANCEMENT] [#532](https://github.com/k8ssandra/k8ssandra-operator/issues/532) Extend ImageConfig type to allow additional parameters for k8ssandra-operator requirements. These include per-image PullPolicy / PullSecrets as well as additional image
* [ENHANCEMENT] [#636](https://github.com/k8ssandra/cass-operator/issues/636) Add support for new field in ImageConfig, imageNamespace. This will allow to override namespace of all images when using private registries. Setting it to empty will remove the namespace entirely.

## v1.22.4

Expand Down
2 changes: 1 addition & 1 deletion apis/config/v1beta1/imageconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type ImagePolicy struct {

ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`

ImageNamespace string `json:"imageNamespace,omitempty"`
ImageNamespace *string `json:"imageNamespace,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down
13 changes: 9 additions & 4 deletions apis/config/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 33 additions & 20 deletions pkg/images/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,43 +78,42 @@ func IsHCDVersionSupported(version string) bool {
return validVersions.MatchString(version)
}

func stripRegistry(image string) string {
func splitRegistry(image string) (registry string, imageNoRegistry string) {
comps := strings.Split(image, "/")

if len(comps) > 1 && (strings.Contains(comps[0], ".") || strings.Contains(comps[0], ":")) {
return strings.Join(comps[1:], "/")
return comps[0], strings.Join(comps[1:], "/")
} else {
return image
return "", image
}
}

func applyNamespaceOverride(image string) string {
namespace := GetImageConfig().ImageNamespace

if namespace == "" {
return image
// applyNamespaceOverride takes only input without registry
func applyNamespaceOverride(imageNoRegistry string) string {
if GetImageConfig().ImageNamespace == nil {
return imageNoRegistry
}

// It can be first or second..
imageNoRegistry := stripRegistry(image)
namespace := *GetImageConfig().ImageNamespace

comps := strings.Split(imageNoRegistry, "/")
if len(comps) > 1 {
noNamespace := strings.Join(comps[1:], "/")
if namespace == "" {
return noNamespace
}
return fmt.Sprintf("%s/%s", namespace, noNamespace)
} else {
return image // We can't process this correctly, we only have 1 component
// We can't process this correctly, we only have 1 component. We do not support a case where the original image has no registry and no namespace.
return imageNoRegistry
}
}

func applyDefaultRegistryOverride(customRegistry, image string) string {
customRegistry = strings.TrimSuffix(customRegistry, "/")

func applyDefaultRegistryOverride(customRegistry, imageNoRegistry string) string {
if customRegistry == "" {
return image
} else {
imageNoRegistry := stripRegistry(image)
return fmt.Sprintf("%s/%s", customRegistry, imageNoRegistry)
return imageNoRegistry
}
return fmt.Sprintf("%s/%s", customRegistry, imageNoRegistry)
}

func getRegistryOverride(imageType string) string {
Expand All @@ -136,9 +135,23 @@ func getRegistryOverride(imageType string) string {
}

func applyOverrides(imageType, image string) string {
registry := getRegistryOverride(imageType)
registryOverride := getRegistryOverride(imageType)
registryOverride = strings.TrimSuffix(registryOverride, "/")
registry, imageNoRegistry := splitRegistry(image)

if registryOverride == "" && GetImageConfig().ImageNamespace == nil {
return image
}

if GetImageConfig().ImageNamespace != nil {
imageNoRegistry = applyNamespaceOverride(imageNoRegistry)
}

if registryOverride != "" {
return applyDefaultRegistryOverride(registryOverride, imageNoRegistry)
}

return applyDefaultRegistryOverride(registry, image)
return applyDefaultRegistryOverride(registry, imageNoRegistry)
}

func GetImageConfig() *configv1beta1.ImageConfig {
Expand Down
13 changes: 10 additions & 3 deletions pkg/images/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/ptr"

configv1beta1 "github.com/k8ssandra/cass-operator/apis/config/v1beta1"
)
Expand Down Expand Up @@ -203,15 +204,15 @@ func TestRepositoryAndNamespaceOverride(t *testing.T) {
assert.NoError(err)
assert.Equal("ghcr.io/datastax/dse-mgmtapi-6_8:6.8.44", path)

imageConfig.ImageNamespace = "enterprise"
imageConfig.ImageNamespace = ptr.To[string]("enterprise")
path, err = GetCassandraImage("dse", "6.8.44")
assert.NoError(err)
assert.Equal("ghcr.io/enterprise/dse-mgmtapi-6_8:6.8.44", path)

imageConfig = configv1beta1.ImageConfig{}
imageConfig.Images = &configv1beta1.Images{}
imageConfig.DefaultImages = &configv1beta1.DefaultImages{}
imageConfig.ImageNamespace = "enterprise"
imageConfig.ImageNamespace = ptr.To[string]("enterprise")
path, err = GetCassandraImage("dse", "6.8.44")
assert.NoError(err)
assert.Equal("enterprise/dse-mgmtapi-6_8:6.8.44", path)
Expand All @@ -228,10 +229,16 @@ func TestRepositoryAndNamespaceOverride(t *testing.T) {
path, err = GetCassandraImage("dse", "6.8.44")
assert.NoError(err)
assert.Equal("cr.dtsx.io/datastax/dse-mgmtapi-6_8:6.8.44", path)
imageConfig.ImageNamespace = "internal"

imageConfig.ImageNamespace = ptr.To[string]("internal")
path, err = GetCassandraImage("dse", "6.8.44")
assert.NoError(err)
assert.Equal("cr.dtsx.io/internal/dse-mgmtapi-6_8:6.8.44", path)

imageConfig.ImageNamespace = ptr.To[string]("")
path, err = GetCassandraImage("dse", "6.8.44")
assert.NoError(err)
assert.Equal("cr.dtsx.io/dse-mgmtapi-6_8:6.8.44", path)
}

func TestImageConfigByteParsing(t *testing.T) {
Expand Down

0 comments on commit 2b79709

Please sign in to comment.