Skip to content

Commit

Permalink
Registry config command (#2220)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cortey authored Sep 30, 2024
1 parent 25cc9fb commit 6f73ee2
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 10 deletions.
2 changes: 2 additions & 0 deletions internal/cmd/alpha/alpha.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package alpha

import (
"context"
"github.com/kyma-project/cli.v3/internal/cmd/alpha/registry"

"github.com/kyma-project/cli.v3/internal/cmd/alpha/access"
"github.com/kyma-project/cli.v3/internal/cmd/alpha/add"
Expand Down Expand Up @@ -38,6 +39,7 @@ func NewAlphaCMD() *cobra.Command {
cmd.AddCommand(modules.NewModulesCMD(config))
cmd.AddCommand(add.NewAddCMD(config))
cmd.AddCommand(remove.NewRemoveCMD(config))
cmd.AddCommand(registry.NewRegistryCMD(config))

return cmd
}
2 changes: 1 addition & 1 deletion internal/cmd/alpha/imageimport/imageimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (pc *provisionConfig) complete(args []string) clierror.Error {

func runImageImport(config *provisionConfig) clierror.Error {
// TODO: Add "serverless is not installed" error message
registryConfig, err := registry.GetConfig(config.Ctx, config.KubeClient)
registryConfig, err := registry.GetInternalConfig(config.Ctx, config.KubeClient)
if err != nil {
return clierror.WrapE(err, clierror.New("failed to load in-cluster registry configuration"))
}
Expand Down
75 changes: 75 additions & 0 deletions internal/cmd/alpha/registry/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package config

import (
"fmt"
"github.com/kyma-project/cli.v3/internal/clierror"
"github.com/kyma-project/cli.v3/internal/cmdcommon"
"github.com/kyma-project/cli.v3/internal/registry"
"github.com/spf13/cobra"
"os"
)

type cfgConfig struct {
*cmdcommon.KymaConfig
cmdcommon.KubeClientConfig

externalurl bool
output string
}

func NewConfigCMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command {
cfg := cfgConfig{
KymaConfig: kymaConfig,
KubeClientConfig: cmdcommon.KubeClientConfig{},
}

cmd := &cobra.Command{
Use: "config",
Short: "Saves Kyma registry dockerconfig to a file",
Long: "Use this command to save Kyma registry dockerconfig to a file",
PreRun: func(_ *cobra.Command, _ []string) {
clierror.Check(cfg.KubeClientConfig.Complete())
},
Run: func(_ *cobra.Command, _ []string) {
clierror.Check(runConfig(&cfg))
},
}

cfg.KubeClientConfig.AddFlag(cmd)
cmd.Flags().BoolVar(&cfg.externalurl, "externalurl", false, "External URL for the Kyma registry.")
cmd.Flags().StringVar(&cfg.output, "output", "", "Path where the output file should be saved to. NOTE: docker expects the file to be named `config.json`.")

return cmd
}

func runConfig(cfg *cfgConfig) clierror.Error {
registryConfig, err := registry.GetExternalConfig(cfg.Ctx, cfg.KubeClient)
if err != nil {
return clierror.WrapE(err, clierror.New("failed to load in-cluster registry configuration"))
}

if cfg.externalurl && cfg.output == "" {
fmt.Print(registryConfig.SecretData.PushRegAddr)
return nil
}

if cfg.externalurl && cfg.output != "" {
writeErr := os.WriteFile(cfg.output, []byte(registryConfig.SecretData.PushRegAddr), os.ModePerm)
if writeErr != nil {
return clierror.New("failed to write docker config to file")
}
return nil
}

if cfg.output == "" {
fmt.Print(registryConfig.SecretData.DockerConfigJSON)
} else {
writeErr := os.WriteFile(cfg.output, []byte(registryConfig.SecretData.DockerConfigJSON), os.ModePerm)
if writeErr != nil {
return clierror.New("failed to write docker config to file")
}
fmt.Print("Docker config saved to ", cfg.output)
}

return nil
}
20 changes: 20 additions & 0 deletions internal/cmd/alpha/registry/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package registry

import (
"github.com/kyma-project/cli.v3/internal/cmd/alpha/registry/config"
"github.com/kyma-project/cli.v3/internal/cmdcommon"
"github.com/spf13/cobra"
)

func NewRegistryCMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command {

cmd := &cobra.Command{
Use: "registry",
Short: "Set of commands for Kyma registry",
Long: `Use this command manage resources related to Kyma registry`,
}

cmd.AddCommand(config.NewConfigCMD(kymaConfig))

return cmd
}
47 changes: 42 additions & 5 deletions internal/registry/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,33 @@ import (
"k8s.io/client-go/kubernetes"
)

type RegistryConfig struct {
type ExternalRegistryConfig struct {
SecretName string
SecretData *SecretData
}

type InternalRegistryConfig struct {
SecretName string
SecretData *SecretData
PodMeta *RegistryPodMeta
}

func GetConfig(ctx context.Context, client kube.Client) (*RegistryConfig, clierror.Error) {
config, err := getConfig(ctx, client)
func GetExternalConfig(ctx context.Context, client kube.Client) (*ExternalRegistryConfig, clierror.Error) {
config, err := getExternalConfig(ctx, client)
if err != nil {
return nil, clierror.Wrap(err,
clierror.New("failed to get external registry configuration",
"make sure cluster is available and properly configured",
"make sure the Docker Registry is installed and in Ready/Warning state.",
),
)
}

return config, nil
}

func GetInternalConfig(ctx context.Context, client kube.Client) (*InternalRegistryConfig, clierror.Error) {
config, err := getInternalConfig(ctx, client)
if err != nil {
return nil, clierror.Wrap(err,
clierror.New("failed to load in-cluster registry configuration",
Expand All @@ -35,12 +54,30 @@ func GetConfig(ctx context.Context, client kube.Client) (*RegistryConfig, clierr
return config, nil
}

func getConfig(ctx context.Context, client kube.Client) (*RegistryConfig, error) {
func getExternalConfig(ctx context.Context, client kube.Client) (*ExternalRegistryConfig, error) {
dockerRegistry, err := getDockerRegistry(ctx, client.Dynamic())
if err != nil {
return nil, err
}
if dockerRegistry.Status.ExternalAccess.Enabled == "false" {
return nil, errors.New("external access is not enabled")
}
secretConfig, err := getRegistrySecretData(ctx, client.Static(), dockerRegistry.Status.ExternalAccess.SecretName, dockerRegistry.GetNamespace())
if err != nil {
return nil, err
}

return &ExternalRegistryConfig{
SecretName: dockerRegistry.Status.ExternalAccess.SecretName,
SecretData: secretConfig,
}, nil
}

func getInternalConfig(ctx context.Context, client kube.Client) (*InternalRegistryConfig, error) {
dockerRegistry, err := getDockerRegistry(ctx, client.Dynamic())
if err != nil {
return nil, err
}
secretConfig, err := getRegistrySecretData(ctx, client.Static(), dockerRegistry.Status.InternalAccess.SecretName, dockerRegistry.GetNamespace())
if err != nil {
return nil, err
Expand All @@ -51,7 +88,7 @@ func getConfig(ctx context.Context, client kube.Client) (*RegistryConfig, error)
return nil, err
}

return &RegistryConfig{
return &InternalRegistryConfig{
SecretName: dockerRegistry.Status.InternalAccess.SecretName,
SecretData: secretConfig,
PodMeta: podMeta,
Expand Down
8 changes: 4 additions & 4 deletions internal/registry/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
)

func TestGetConfig(t *testing.T) {
t.Run("Should return the RegistryConfig", func(t *testing.T) {
t.Run("Should return the InternalRegistryConfig", func(t *testing.T) {
// given
testRegistrySvc := fixTestRegistrySvc()
testRegistryPod := fixTestRegistryPod()
Expand All @@ -29,7 +29,7 @@ func TestGetConfig(t *testing.T) {
scheme.AddKnownTypes(DockerRegistryGVR.GroupVersion(), testDockerRegistry)
dynamic := dynamic_fake.NewSimpleDynamicClient(scheme, testDockerRegistry)

expectedRegistryConfig := &RegistryConfig{
expectedRegistryConfig := &InternalRegistryConfig{
SecretName: testRegistrySecret.GetName(),
SecretData: &SecretData{
DockerConfigJSON: string(testRegistrySecret.Data[".dockerconfigjson"]),
Expand All @@ -51,7 +51,7 @@ func TestGetConfig(t *testing.T) {
}

// when
config, err := GetConfig(context.Background(), kubeClient)
config, err := GetInternalConfig(context.Background(), kubeClient)

// then
require.Nil(t, err)
Expand All @@ -60,7 +60,7 @@ func TestGetConfig(t *testing.T) {
}

func Test_getRegistrySecretConfig(t *testing.T) {
t.Run("Should return the RegistryConfig", func(t *testing.T) {
t.Run("Should return the InternalRegistryConfig", func(t *testing.T) {
// given
testRegistrySecret := fixTestRegistrySecret()
client := k8s_fake.NewSimpleClientset(testRegistrySecret)
Expand Down
6 changes: 6 additions & 0 deletions internal/registry/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ type InternalAccess struct {
SecretName string `json:"secretName,omitempty"`
}

type ExternalAccess struct {
SecretName string `json:"secretName,omitempty"`
Enabled string `json:"enabled,omitempty"`
}

type DockerRegistryStatus struct {
State string `json:"state,omitempty"`
Served string `json:"served"`
InternalAccess InternalAccess `json:"internalAccess"`
ExternalAccess ExternalAccess `json:"externalAccess"`
}

0 comments on commit 6f73ee2

Please sign in to comment.