Unverified Commit 75fac5f5 authored by bryanl's avatar bryanl
Browse files

Allow user to skip inclusion of default registries



Introduces a new init flag `--skip-default-registries` that skips adding
incubator to the intial list of available registries. This will allow
`ks` to work without access to GitHub.

Users can add additional registries at a later time with `ks registry
add`.

Fixes #204
Signed-off-by: default avatarbryanl <bryanliles@gmail.com>
parent bb346e6f
...@@ -74,6 +74,8 @@ const ( ...@@ -74,6 +74,8 @@ const (
OptionServer = "server" OptionServer = "server"
// OptionServerURI is serverURI option. // OptionServerURI is serverURI option.
OptionServerURI = "server-uri" OptionServerURI = "server-uri"
// OptionSkipDefaultRegistries is skipDefaultRegistries option. Used by init.
OptionSkipDefaultRegistries = "skip-default-registries"
// OptionSkipGc is skipGc option. // OptionSkipGc is skipGc option.
OptionSkipGc = "skip-gc" OptionSkipGc = "skip-gc"
// OptionSpecFlag is specFlag option. Used for setting k8s spec. // OptionSpecFlag is specFlag option. Used for setting k8s spec.
......
...@@ -42,12 +42,13 @@ type initIncubatorFn func() (registry.Registry, error) ...@@ -42,12 +42,13 @@ type initIncubatorFn func() (registry.Registry, error)
// Init creates a component namespace // Init creates a component namespace
type Init struct { type Init struct {
fs afero.Fs fs afero.Fs
name string name string
rootPath string rootPath string
k8sSpecFlag string k8sSpecFlag string
serverURI string serverURI string
namespace string namespace string
skipDefaultRegistries bool
appInitFn appInitFn appInitFn appInitFn
initIncubatorFn initIncubatorFn initIncubatorFn initIncubatorFn
...@@ -58,12 +59,13 @@ func NewInit(m map[string]interface{}) (*Init, error) { ...@@ -58,12 +59,13 @@ func NewInit(m map[string]interface{}) (*Init, error) {
ol := newOptionLoader(m) ol := newOptionLoader(m)
i := &Init{ i := &Init{
fs: ol.loadFs(OptionFs), fs: ol.loadFs(OptionFs),
name: ol.loadString(OptionName), name: ol.loadString(OptionName),
rootPath: ol.loadString(OptionRootPath), rootPath: ol.loadString(OptionRootPath),
k8sSpecFlag: ol.loadString(OptionSpecFlag), k8sSpecFlag: ol.loadString(OptionSpecFlag),
serverURI: ol.loadOptionalString(OptionServer), serverURI: ol.loadOptionalString(OptionServer),
namespace: ol.loadString(OptionNamespaceName), namespace: ol.loadString(OptionNamespaceName),
skipDefaultRegistries: ol.loadBool(OptionSkipDefaultRegistries),
appInitFn: appinit.Init, appInitFn: appinit.Init,
initIncubatorFn: initIncubator, initIncubatorFn: initIncubator,
...@@ -78,12 +80,16 @@ func NewInit(m map[string]interface{}) (*Init, error) { ...@@ -78,12 +80,16 @@ func NewInit(m map[string]interface{}) (*Init, error) {
// Run runs that ns create action. // Run runs that ns create action.
func (i *Init) Run() error { func (i *Init) Run() error {
gh, err := i.initIncubatorFn() var registries []registry.Registry
if err != nil {
return err
}
registries := []registry.Registry{gh} if !i.skipDefaultRegistries {
gh, err := i.initIncubatorFn()
if err != nil {
return err
}
registries = append(registries, gh)
}
return i.appInitFn( return i.appInitFn(
i.fs, i.fs,
......
...@@ -35,45 +35,68 @@ func TestInit(t *testing.T) { ...@@ -35,45 +35,68 @@ func TestInit(t *testing.T) {
aServerURI := "http://example.com" aServerURI := "http://example.com"
aNamespace := "my-namespace" aNamespace := "my-namespace"
in := map[string]interface{}{ cases := []struct {
OptionFs: aFs, name string
OptionName: aName, skipRegistries bool
OptionRootPath: aRootPath, }{
OptionSpecFlag: aK8sSpecFlag, {
OptionServer: aServerURI, name: "with registries",
OptionNamespaceName: aNamespace, },
{
name: "without registries",
skipRegistries: true,
},
} }
a, err := NewInit(in) for _, tc := range cases {
require.NoError(t, err) t.Run(tc.name, func(t *testing.T) {
in := map[string]interface{}{
OptionFs: aFs,
OptionName: aName,
OptionRootPath: aRootPath,
OptionSpecFlag: aK8sSpecFlag,
OptionServer: aServerURI,
OptionNamespaceName: aNamespace,
OptionSkipDefaultRegistries: tc.skipRegistries,
}
a.appInitFn = func(fs afero.Fs, name, rootPath, k8sSpecFlag, serverURI, namespace string, registries []registry.Registry) error { a, err := NewInit(in)
assert.Equal(t, aFs, fs) require.NoError(t, err)
assert.Equal(t, aName, name)
assert.Equal(t, aRootPath, rootPath)
assert.Equal(t, aK8sSpecFlag, k8sSpecFlag)
assert.Equal(t, aServerURI, serverURI)
assert.Equal(t, aNamespace, namespace)
assert.Len(t, registries, 1) a.appInitFn = func(fs afero.Fs, name, rootPath, k8sSpecFlag, serverURI, namespace string, registries []registry.Registry) error {
r := registries[0] assert.Equal(t, aFs, fs)
assert.Equal(t, aName, name)
assert.Equal(t, aRootPath, rootPath)
assert.Equal(t, aK8sSpecFlag, k8sSpecFlag)
assert.Equal(t, aServerURI, serverURI)
assert.Equal(t, aNamespace, namespace)
assert.Equal(t, "github", r.Protocol()) if !tc.skipRegistries {
assert.Equal(t, "github.com/ksonnet/parts/tree/master/incubator", r.URI()) assert.Len(t, registries, 1)
assert.Equal(t, "incubator", r.Name()) r := registries[0]
return nil assert.Equal(t, "github", r.Protocol())
} assert.Equal(t, "github.com/ksonnet/parts/tree/master/incubator", r.URI())
assert.Equal(t, "incubator", r.Name())
} else {
assert.Empty(t, registries)
}
return nil
}
a.initIncubatorFn = func() (registry.Registry, error) {
r := &rmocks.Registry{}
r.On("Protocol").Return("github")
r.On("URI").Return("github.com/ksonnet/parts/tree/master/incubator")
r.On("Name").Return("incubator")
return r, nil
}
a.initIncubatorFn = func() (registry.Registry, error) { err = a.Run()
r := &rmocks.Registry{} require.NoError(t, err)
r.On("Protocol").Return("github") })
r.On("URI").Return("github.com/ksonnet/parts/tree/master/incubator")
r.On("Name").Return("incubator")
return r, nil
} }
err = a.Run()
require.NoError(t, err)
}) })
} }
...@@ -18,18 +18,29 @@ package cmd ...@@ -18,18 +18,29 @@ package cmd
const ( const (
// For use in the commands (e.g., diff, apply, delete) that require either an // For use in the commands (e.g., diff, apply, delete) that require either an
// environment or the -f flag. // environment or the -f flag.
flagComponent = "component" flagAPISpec = "api-spec"
flagCreate = "create" flagComponent = "component"
flagDryRun = "dry-run" flagCreate = "create"
flagEnv = "env" flagDir = "dir"
flagFilename = "filename" flagDryRun = "dry-run"
flagGcTag = "gc-tag" flagEnv = "env"
flagIndex = "index" flagExtVar = "ext-str"
flagNamespace = "namespace" flagExtVarFile = "ext-str-file"
flagSkipGc = "skip-gc" flagFilename = "filename"
flagOutput = "output" flagGcTag = "gc-tag"
flagOverride = "override" flagIndex = "index"
flagVersion = "version" flagJpath = "jpath"
flagNamespace = "namespace"
flagResolver = "resolve-images"
flagResolvFail = "resolve-images-error"
flagSkipDefaultRegistries = "skip-default-registries"
flagSkipGc = "skip-gc"
flagTlaVar = "tla-str"
flagTlaVarFile = "tla-str-file"
flagOutput = "output"
flagOverride = "override"
flagVerbose = "verbose"
flagVersion = "version"
shortComponent = "c" shortComponent = "c"
shortFilename = "f" shortFilename = "f"
......
...@@ -21,14 +21,19 @@ import ( ...@@ -21,14 +21,19 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/spf13/viper"
"github.com/ksonnet/ksonnet/actions" "github.com/ksonnet/ksonnet/actions"
"github.com/ksonnet/ksonnet/client" "github.com/ksonnet/ksonnet/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const ( const (
flagInitDir = "dir"
initShortDesc = "Initialize a ksonnet application" initShortDesc = "Initialize a ksonnet application"
vInitAPISpec = "init-api-spec"
vInitDir = "init-dir"
vInitSkipDefaultRegistries = "init-skip-default-registries"
) )
var ( var (
...@@ -37,13 +42,19 @@ var ( ...@@ -37,13 +42,19 @@ var (
func init() { func init() {
RootCmd.AddCommand(initCmd) RootCmd.AddCommand(initCmd)
initClientConfig = client.NewDefaultClientConfig()
initClientConfig.BindClientGoFlags(initCmd)
initCmd.Flags().String(flagDir, "", "Ksonnet application directory")
viper.BindPFlag(vInitDir, initCmd.Flag(flagDir))
// TODO: We need to make this default to checking the `kubeconfig` file. // TODO: We need to make this default to checking the `kubeconfig` file.
initCmd.PersistentFlags().String(flagAPISpec, "", initCmd.Flags().String(flagAPISpec, "",
"Manually specified Kubernetes API version. The corresponding OpenAPI spec is used to generate ksonnet's Kubernetes libraries") "Manually specified Kubernetes API version. The corresponding OpenAPI spec is used to generate ksonnet's Kubernetes libraries")
viper.BindPFlag(vInitAPISpec, initCmd.Flag(flagAPISpec))
initClientConfig = client.NewDefaultClientConfig() initCmd.Flags().Bool(flagSkipDefaultRegistries, false, "Skip configuration of default registries")
initClientConfig.BindClientGoFlags(initCmd) viper.BindPFlag(vInitSkipDefaultRegistries, initCmd.Flag(flagSkipDefaultRegistries))
initCmd.Flags().String(flagInitDir, "", "Ksonnet application directory")
} }
var initCmd = &cobra.Command{ var initCmd = &cobra.Command{
...@@ -61,10 +72,7 @@ var initCmd = &cobra.Command{ ...@@ -61,10 +72,7 @@ var initCmd = &cobra.Command{
return err return err
} }
initDir, err := flags.GetString(flagInitDir) initDir := viper.GetString(vInitDir)
if err != nil {
return err
}
appRoot, err := genKsRoot(appName, wd, initDir) appRoot, err := genKsRoot(appName, wd, initDir)
if err != nil { if err != nil {
...@@ -76,21 +84,19 @@ var initCmd = &cobra.Command{ ...@@ -76,21 +84,19 @@ var initCmd = &cobra.Command{
return err return err
} }
specFlag, err := flags.GetString(flagAPISpec) specFlag := viper.GetString(vInitAPISpec)
if err != nil {
return err
}
if specFlag == "" { if specFlag == "" {
specFlag = initClientConfig.GetAPISpec(server) specFlag = initClientConfig.GetAPISpec(server)
} }
m := map[string]interface{}{ m := map[string]interface{}{
actions.OptionFs: appFs, actions.OptionFs: appFs,
actions.OptionName: appName, actions.OptionName: appName,
actions.OptionRootPath: appRoot, actions.OptionRootPath: appRoot,
actions.OptionSpecFlag: specFlag, actions.OptionSpecFlag: specFlag,
actions.OptionServer: server, actions.OptionServer: server,
actions.OptionNamespaceName: namespace, actions.OptionNamespaceName: namespace,
actions.OptionSkipDefaultRegistries: viper.GetBool(vInitSkipDefaultRegistries),
} }
return runAction(actionInit, m) return runAction(actionInit, m)
......
...@@ -36,12 +36,13 @@ func Test_initCmd(t *testing.T) { ...@@ -36,12 +36,13 @@ func Test_initCmd(t *testing.T) {
args: []string{"init", "app", "--namespace", "new-namespace", "--server", "http://127.0.0.1"}, args: []string{"init", "app", "--namespace", "new-namespace", "--server", "http://127.0.0.1"},
action: actionInit, action: actionInit,
expected: map[string]interface{}{ expected: map[string]interface{}{
actions.OptionFs: appFs, actions.OptionFs: appFs,
actions.OptionName: "app", actions.OptionName: "app",
actions.OptionRootPath: root, actions.OptionRootPath: root,
actions.OptionServer: "http://127.0.0.1", actions.OptionServer: "http://127.0.0.1",
actions.OptionSpecFlag: "version:v1.7.0", actions.OptionSpecFlag: "version:v1.7.0",
actions.OptionNamespaceName: "new-namespace", actions.OptionNamespaceName: "new-namespace",
actions.OptionSkipDefaultRegistries: false,
}, },
}, },
} }
......
...@@ -45,18 +45,6 @@ import ( ...@@ -45,18 +45,6 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth" _ "k8s.io/client-go/plugin/pkg/client/auth"
) )
const (
flagVerbose = "verbose"
flagJpath = "jpath"
flagExtVar = "ext-str"
flagExtVarFile = "ext-str-file"
flagTlaVar = "tla-str"
flagTlaVarFile = "tla-str-file"
flagResolver = "resolve-images"
flagResolvFail = "resolve-images-error"
flagAPISpec = "api-spec"
)
var ( var (
appFs = afero.NewOsFs() appFs = afero.NewOsFs()
ka app.App ka app.App
......
...@@ -97,6 +97,7 @@ ks init app-name --dir=custom-location ...@@ -97,6 +97,7 @@ ks init app-name --dir=custom-location
--password string Password for basic authentication to the API server --password string Password for basic authentication to the API server
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
--server string The address and port of the Kubernetes API server --server string The address and port of the Kubernetes API server
--skip-default-registries Skip configuration of default registries
--token string Bearer token for authentication to the API server --token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use --user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server --username string Username for basic authentication to the API server
......
...@@ -162,9 +162,10 @@ func (e *e2e) initApp(options *initOptions) app { ...@@ -162,9 +162,10 @@ func (e *e2e) initApp(options *initOptions) app {
} }
type initOptions struct { type initOptions struct {
server string server string
context string context string
namespace string namespace string
skipRegistries bool
} }
func (o *initOptions) toSlice() ([]string, error) { func (o *initOptions) toSlice() ([]string, error) {
...@@ -187,5 +188,9 @@ func (o *initOptions) toSlice() ([]string, error) { ...@@ -187,5 +188,9 @@ func (o *initOptions) toSlice() ([]string, error) {
options = append(options, "--namespace", o.namespace) options = append(options, "--namespace", o.namespace)
} }
if o.skipRegistries {
options = append(options, "--skip-default-registries")
}
return options, nil return options, nil
} }
// +build e2e
package e2e
import (
"path/filepath"
. "github.com/onsi/ginkgo"
)
var _ = Describe("ks init", func() {
var a app
var opts = &initOptions{}
JustBeforeEach(func() {
a = e.initApp(opts)
})
Context("in general", func() {
It("doesn't generate default registries", func() {
o := a.registryList()
assertOutput(filepath.Join("init", "registry-output.txt"), o.stdout)
})
})
Context("without default registries", func() {
BeforeEach(func() {
opts.skipRegistries = true
})
It("doesn't generate default registries", func() {
o := a.registryList()
assertOutput(filepath.Join("init", "skip-registry-output.txt"), o.stdout)
})
})
})
NAME OVERRIDE PROTOCOL URI
==== ======== ======== ===
incubator github github.com/ksonnet/parts/tree/master/incubator
NAME OVERRIDE PROTOCOL URI
==== ======== ======== ===
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment