Skip to content

Commit

Permalink
Add command to ouput default image registry config (#1022)
Browse files Browse the repository at this point in the history
This adds the subcommand `default-image-config` to `gen` to output the
default image registry config used with the `images` and `run` commands.
It will generate the config based on the version of Kubernetes that is
configured for use.

This simplifies the process for users as the registries for the E2E
tests differ for different versions of Kubernetes.

Signed-off-by: Bridget McErlean <bmcerlean@vmware.com>
  • Loading branch information
zubron committed Dec 2, 2019
1 parent 44be251 commit cff00ca
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 28 deletions.
79 changes: 79 additions & 0 deletions cmd/sonobuoy/app/gen_image_repo_config.go
@@ -0,0 +1,79 @@
/*
Copyright the Sonobuoy contributors 2019
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 app

import (
"fmt"
"os"

"github.com/vmware-tanzu/sonobuoy/pkg/errlog"
"github.com/vmware-tanzu/sonobuoy/pkg/image"

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
yaml "gopkg.in/yaml.v2"
)

// NewCmdGenImageRepoConfig creates the `default-image-config` subcommand for `gen`
// which will print out the default image registry config for the E2E tests which is
// used with the `images` and `run` command.
func NewCmdGenImageRepoConfig() *cobra.Command {
var cfg Kubeconfig
cmd := &cobra.Command{
Use: "default-image-config",
Short: "Generates the default image registry config for the e2e plugin",
Run: func(cmd *cobra.Command, args []string) {
s, err := defaultImageRegConfig(&cfg)
if err != nil {
errlog.LogError(err)
os.Exit(1)
}
fmt.Println(string(s))
},
Args: cobra.NoArgs,
}

genPluginSet := pflag.NewFlagSet("default-image-config", pflag.ExitOnError)
AddKubeconfigFlag(&cfg, genPluginSet)
cmd.Flags().AddFlagSet(genPluginSet)

return cmd
}

func defaultImageRegConfig(cfg *Kubeconfig) ([]byte, error) {
sbc, err := getSonobuoyClientFromKubecfg(*cfg)
if err != nil {
return []byte{}, errors.Wrap(err, "could not create sonobuoy client")
}

version, err := sbc.Version()
if err != nil {
return []byte{}, errors.Wrap(err, "couldn't get Kubernetes version")
}

registries, err := image.GetDefaultImageRegistries(version)
if err != nil {
return []byte{}, errors.Wrap(err, "couldn't get image registries for version")
}

d, err := yaml.Marshal(&registries)
if err != nil {
return []byte{}, errors.Wrap(err, "couldn't marshal registry information")
}
return d, nil
}
3 changes: 2 additions & 1 deletion cmd/sonobuoy/app/root.go
Expand Up @@ -20,8 +20,8 @@ import (
"flag"

"github.com/vmware-tanzu/sonobuoy/pkg/errlog"
"github.com/spf13/cobra"

"github.com/spf13/cobra"
"k8s.io/klog"
)

Expand All @@ -42,6 +42,7 @@ func NewSonobuoyCommand() *cobra.Command {
gen := NewCmdGen()
gen.AddCommand(NewCmdGenPluginDef())
gen.AddCommand(NewCmdGenConfig())
gen.AddCommand(NewCmdGenImageRepoConfig())
cmds.AddCommand(gen)

cmds.AddCommand(NewCmdLogs())
Expand Down
112 changes: 85 additions & 27 deletions pkg/image/manifest.go
Expand Up @@ -23,24 +23,36 @@ import (
yaml "gopkg.in/yaml.v2"
)

const (
dockerLibraryRegistry = "docker.io/library"
e2eRegistry = "gcr.io/kubernetes-e2e-test-images"
etcdRegistry = "quay.io/coreos"
gcAuthenticatedRegistry = "gcr.io/authenticated-image-pulling"
gcRegistry = "k8s.gcr.io"
gcrReleaseRegistry = "gcr.io/gke-release"
googleContainerRegistry = "gcr.io/google-containers"
invalidRegistry = "invalid.com/invalid"
privateRegistry = "gcr.io/k8s-authenticated-test"
quayK8sCSI = "quay.io/k8scsi"
sampleRegistry = "gcr.io/google-samples"
)

// RegistryList holds public and private image registries
type RegistryList struct {
GcAuthenticatedRegistry string `yaml:"gcAuthenticatedRegistry"`
DockerLibraryRegistry string `yaml:"dockerLibraryRegistry"`
E2eRegistry string `yaml:"e2eRegistry"`
InvalidRegistry string `yaml:"invalidRegistry"`
GcRegistry string `yaml:"gcRegistry"`
GcrReleaseRegistry string `yaml:"gcrReleaseRegistry"`
GoogleContainerRegistry string `yaml:"googleContainerRegistry"`
PrivateRegistry string `yaml:"privateRegistry"`
SampleRegistry string `yaml:"sampleRegistry"`
QuayK8sCSI string `yaml:"quayK8sCSI"`

// Registry used in v1.14.0 only
EtcdRegistry string `yaml:"etcdRegistry"`

K8sVersion *version.Version
Images map[int]Config
DockerLibraryRegistry string `yaml:"dockerLibraryRegistry,omitempty"`
E2eRegistry string `yaml:"e2eRegistry,omitempty"`
EtcdRegistry string `yaml:"etcdRegistry,omitempty"`
GcAuthenticatedRegistry string `yaml:"gcAuthenticatedRegistry,omitempty"`
GcRegistry string `yaml:"gcRegistry,omitempty"`
GcrReleaseRegistry string `yaml:"gcrReleaseRegistry,omitempty"`
GoogleContainerRegistry string `yaml:"googleContainerRegistry,omitempty"`
InvalidRegistry string `yaml:"invalidRegistry,omitempty"`
PrivateRegistry string `yaml:"privateRegistry,omitempty"`
QuayK8sCSI string `yaml:"quayK8sCSI,omitempty"`
SampleRegistry string `yaml:"sampleRegistry,omitempty"`

K8sVersion *version.Version `yaml:"-"`
Images map[int]Config `yaml:"-"`
}

// Config holds an images registry, name, and version
Expand All @@ -53,17 +65,17 @@ type Config struct {
// NewRegistryList returns a default registry or one that matches a config file passed
func NewRegistryList(repoConfig, k8sVersion string) (*RegistryList, error) {
registry := &RegistryList{
GcAuthenticatedRegistry: "gcr.io/authenticated-image-pulling",
DockerLibraryRegistry: "docker.io/library",
E2eRegistry: "gcr.io/kubernetes-e2e-test-images",
InvalidRegistry: "invalid.com/invalid",
GcRegistry: "k8s.gcr.io",
GcrReleaseRegistry: "gcr.io/gke-release",
GoogleContainerRegistry: "gcr.io/google-containers",
PrivateRegistry: "gcr.io/k8s-authenticated-test",
SampleRegistry: "gcr.io/google-samples",
QuayK8sCSI: "quay.io/k8scsi",
EtcdRegistry: "quay.io/coreos",
DockerLibraryRegistry: dockerLibraryRegistry,
E2eRegistry: e2eRegistry,
EtcdRegistry: etcdRegistry,
GcAuthenticatedRegistry: gcAuthenticatedRegistry,
GcRegistry: gcRegistry,
GcrReleaseRegistry: gcrReleaseRegistry,
GoogleContainerRegistry: googleContainerRegistry,
InvalidRegistry: invalidRegistry,
PrivateRegistry: privateRegistry,
QuayK8sCSI: quayK8sCSI,
SampleRegistry: sampleRegistry,
}

// Load in a config file
Expand Down Expand Up @@ -109,6 +121,52 @@ func (r *RegistryList) GetImageConfigs() (map[string]Config, error) {
return map[string]Config{}, fmt.Errorf("No matching configuration for k8s version: %v", r.K8sVersion)
}

// GetDefaultImageRegistries returns the default default image registries used for
// a given version of the Kubernetes E2E tests
func GetDefaultImageRegistries(version string) (*RegistryList, error) {
// Init images for k8s version & repos configured
v, err := validateVersion(version)
if err != nil {
return nil, err
}

switch v.Segments()[0] {
case 1:
switch v.Segments()[1] {
case 13, 14:
return &RegistryList{
DockerLibraryRegistry: dockerLibraryRegistry,
E2eRegistry: e2eRegistry,
EtcdRegistry: etcdRegistry,
GcRegistry: gcRegistry,
SampleRegistry: sampleRegistry,
}, nil
case 15:
return &RegistryList{
DockerLibraryRegistry: dockerLibraryRegistry,
E2eRegistry: e2eRegistry,
GcRegistry: gcRegistry,
SampleRegistry: sampleRegistry,
}, nil
case 16:
return &RegistryList{
DockerLibraryRegistry: dockerLibraryRegistry,
E2eRegistry: e2eRegistry,
GcRegistry: gcRegistry,
GoogleContainerRegistry: googleContainerRegistry,
SampleRegistry: sampleRegistry,

// The following keys are used in the v1.16 registry list however their images
// cannot be pulled as they are used as part of tests for checking image pull
// behavior. They are omitted from the resulting config.
// InvalidRegistry: invalidRegistry,
// GcAuthenticatedRegistry: gcAuthenticatedRegistry,
}, nil
}
}
return nil, fmt.Errorf("No matching configuration for k8s version: %v", v)
}

// GetE2EImage returns the fully qualified URI to an image (including version)
func (i *Config) GetE2EImage() string {
return fmt.Sprintf("%s/%s:%s", i.registry, i.name, i.version)
Expand Down
78 changes: 78 additions & 0 deletions pkg/image/manifest_test.go
@@ -0,0 +1,78 @@
/*
Copyright the Sonobuoy contributors 2019
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 image

import (
"strings"
"testing"
)

func TestGetDefaultImageRegistryVersionValidation(t *testing.T) {
tests := []struct {
name string
version string
error bool
expect string
}{
{
name: "Non valid version results in error",
version: "not-a-valid-version",
error: true,
expect: "\"not-a-valid-version\" is invalid",
},
{
name: "v1.13 is valid",
version: "v1.13.0",
error: false,
},
{
name: "v1.14 is valid",
version: "v1.14.0",
error: false,
},
{
name: "v1.15 is valid",
version: "v1.15.0",
error: false,
},
{
name: "v1.16 is valid",
version: "v1.16.0",
error: false,
},
{
name: "v1.12 is not valid",
version: "v1.12.0",
error: true,
expect: "No matching configuration for k8s version: 1.12",
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
_, err := GetDefaultImageRegistries(tc.version)
if tc.error && err == nil {
t.Fatal("expected error, got nil")
} else if !tc.error && err != nil {
t.Fatalf("expected no error, got %v", err)
} else if tc.error && !strings.Contains(err.Error(), tc.expect) {
t.Fatalf("expected error to contain %q, got %v", tc.expect, err.Error())
}

})
}
}

0 comments on commit cff00ca

Please sign in to comment.