From 4e0b163e08a28250facf21555bc8f72c9f58fc28 Mon Sep 17 00:00:00 2001 From: Jessica Yuen <im.jessicayuen@gmail.com> Date: Thu, 14 Dec 2017 15:59:09 -0800 Subject: [PATCH] Implement command `ks registry add` Currently users are unable to add their own registries through the CLI. This limits them to a small subset of prototypes found in the default incubator registry. This commit will add the command `ks registry add`, that allows users to add registries supporting the `github` protocol. It will be of the form `ks registry add <registry-name> <registry-uri> [--version]`. If a version is not specified, `latest` will be used. Signed-off-by: Jessica Yuen <im.jessicayuen@gmail.com> --- cmd/registry.go | 61 +++++++++++++++++++++++++++ docs/cli-reference/ks_registry.md | 1 + docs/cli-reference/ks_registry_add.md | 59 ++++++++++++++++++++++++++ metadata/registry.go | 46 ++++++++++---------- pkg/kubecfg/registry.go | 44 +++++++++++++++++++ 5 files changed, 187 insertions(+), 24 deletions(-) create mode 100644 docs/cli-reference/ks_registry_add.md create mode 100644 pkg/kubecfg/registry.go diff --git a/cmd/registry.go b/cmd/registry.go index 6f6b8500..a2a77194 100644 --- a/cmd/registry.go +++ b/cmd/registry.go @@ -6,19 +6,28 @@ import ( "strings" "github.com/ksonnet/ksonnet/metadata" + "github.com/ksonnet/ksonnet/pkg/kubecfg" "github.com/ksonnet/ksonnet/utils" "github.com/spf13/cobra" ) +const ( + flagRegistryVersion = "version" +) + var regShortDesc = map[string]string{ "list": "List all registries known to the current ksonnet app.", "describe": "Describe a ksonnet registry and the packages it contains", + "add": "Add a registry to the current ksonnet app", } func init() { RootCmd.AddCommand(registryCmd) registryCmd.AddCommand(registryListCmd) registryCmd.AddCommand(registryDescribeCmd) + registryCmd.AddCommand(registryAddCmd) + + registryAddCmd.PersistentFlags().String(flagRegistryVersion, "", "Version of the registry to add") } var registryCmd = &cobra.Command{ @@ -182,3 +191,55 @@ by ` + "`<registry-name>`" + `. Specifically, it displays the following: ### Syntax `, } + +var registryAddCmd = &cobra.Command{ + Use: "add <registry-name> <registry-uri>", + Short: regShortDesc["add"], + RunE: func(cmd *cobra.Command, args []string) error { + flags := cmd.Flags() + + if len(args) != 2 { + return fmt.Errorf("Command 'registry add' takes two arguments, which is the name and the repository address of the registry to add") + } + + name := args[0] + uri := args[1] + + version, err := flags.GetString(flagRegistryVersion) + if err != nil { + return err + } + + // TODO allow protocol to be specified by flag once there is greater + // support for other protocol types. + return kubecfg.NewRegistryAddCmd(name, "github", uri, version).Run() + }, + + Long: ` +The ` + "`add`" + ` command allows custom registries to be added to your ksonnet app. + +A registry is uniquely identified by its: + +1. Name +2. Version + +Currently, only registries supporting the GitHub protocol can be added. + +All registries must specify a unique name and URI where the registry lives. +Optionally, a version can be provided. If a version is not specified, it will +default to ` + "`latest`" + `. + + +### Related Commands + +* ` + "`ks registry list` " + `— ` + regShortDesc["list"] + ` + +### Syntax +`, + Example: `# Add a registry with the name 'databases' at the uri 'github.com/example' +ks registry add databases github.com/example + +# Add a registry with the name 'databases' at the uri 'github.com/example' and +# the version 0.0.1 +ks registry add databases github.com/example --version=0.0.1`, +} diff --git a/docs/cli-reference/ks_registry.md b/docs/cli-reference/ks_registry.md index 1cc2cba2..b0b86bc3 100644 --- a/docs/cli-reference/ks_registry.md +++ b/docs/cli-reference/ks_registry.md @@ -35,6 +35,7 @@ ks registry ### SEE ALSO * [ks](ks.md) - Configure your application to deploy to a Kubernetes cluster +* [ks registry add](ks_registry_add.md) - Add a registry to the current ksonnet app * [ks registry describe](ks_registry_describe.md) - Describe a ksonnet registry and the packages it contains * [ks registry list](ks_registry_list.md) - List all registries known to the current ksonnet app. diff --git a/docs/cli-reference/ks_registry_add.md b/docs/cli-reference/ks_registry_add.md new file mode 100644 index 00000000..636be31b --- /dev/null +++ b/docs/cli-reference/ks_registry_add.md @@ -0,0 +1,59 @@ +## ks registry add + +Add a registry to the current ksonnet app + +### Synopsis + + + +The `add` command allows custom registries to be added to your ksonnet app. + +A registry is uniquely identified by its: + +1. Name +2. Version + +Currently, only registries supporting the GitHub protocol can be added. + +All registries must specify a unique name and URI where the registry lives. +Optionally, a version can be provided. If a version is not specified, it will +default to `latest`. + + +### Related Commands + +* `ks registry list` — List all registries known to the current ksonnet app. + +### Syntax + + +``` +ks registry add <registry-name> <registry-uri> +``` + +### Examples + +``` +# Add a registry with the name 'databases' at the uri 'github.com/example' +ks registry add databases github.com/example + +# Add a registry with the name 'databases' at the uri 'github.com/example' and +# the version 0.0.1 +ks registry add databases github.com/example --version=0.0.1 +``` + +### Options + +``` + --version string Version of the registry to add +``` + +### Options inherited from parent commands + +``` + -v, --verbose count[=-1] Increase verbosity. May be given multiple times. +``` + +### SEE ALSO +* [ks registry](ks_registry.md) - Manage registries for current project + diff --git a/metadata/registry.go b/metadata/registry.go index 24fb22e9..38b6b171 100644 --- a/metadata/registry.go +++ b/metadata/registry.go @@ -351,33 +351,31 @@ func (m *manager) getOrCacheRegistry(gh registry.Manager) (*registry.Spec, error registrySpecFile := m.registryPath(gh) registrySpec, exists, err := m.registrySpecFromFile(registrySpecFile) if !exists { - return nil, fmt.Errorf("Registry '%s' does not exist", gh.MakeRegistryRefSpec().Name) - } else if err != nil { - return nil, err - } - - // If failed, use the protocol to try to retrieve app specification. - registrySpec, err = gh.FetchRegistrySpec() - if err != nil { - return nil, err - } + // If failed, use the protocol to try to retrieve app specification. + registrySpec, err = gh.FetchRegistrySpec() + if err != nil { + return nil, err + } - registrySpecBytes, err := registrySpec.Marshal() - if err != nil { - return nil, err - } + registrySpecBytes, err := registrySpec.Marshal() + if err != nil { + return nil, err + } - // NOTE: We call mkdir after getting the registry spec, since a - // network call might fail and leave this half-initialized empty - // directory. - registrySpecDir := appendToAbsPath(m.registriesPath, gh.RegistrySpecDir()) - err = m.appFS.MkdirAll(string(registrySpecDir), defaultFolderPermissions) - if err != nil { - return nil, err - } + // NOTE: We call mkdir after getting the registry spec, since a + // network call might fail and leave this half-initialized empty + // directory. + registrySpecDir := appendToAbsPath(m.registriesPath, gh.RegistrySpecDir()) + err = m.appFS.MkdirAll(string(registrySpecDir), defaultFolderPermissions) + if err != nil { + return nil, err + } - err = afero.WriteFile(m.appFS, string(registrySpecFile), registrySpecBytes, defaultFilePermissions) - if err != nil { + err = afero.WriteFile(m.appFS, string(registrySpecFile), registrySpecBytes, defaultFilePermissions) + if err != nil { + return nil, err + } + } else if err != nil { return nil, err } diff --git a/pkg/kubecfg/registry.go b/pkg/kubecfg/registry.go new file mode 100644 index 00000000..4de55f78 --- /dev/null +++ b/pkg/kubecfg/registry.go @@ -0,0 +1,44 @@ +// Copyright 2017 The ksonnet authors +// +// +// 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 kubecfg + +// RegistryAddCmd contains the metadata needed to create a registry. +type RegistryAddCmd struct { + name string + protocol string + uri string + version string +} + +// NewRegistryAddCmd initializes a RegistryAddCmd. +func NewRegistryAddCmd(name, protocol, uri, version string) *RegistryAddCmd { + if version == "" { + version = "latest" + } + + return &RegistryAddCmd{name: name, protocol: protocol, uri: uri, version: version} +} + +// Run adds the registry to the ksonnet project. +func (c *RegistryAddCmd) Run() error { + manager, err := manager() + if err != nil { + return err + } + + _, err = manager.AddRegistry(c.name, c.protocol, c.uri, c.version) + return err +} -- GitLab