Kinflate: refactoring inputs flags forn config/map to common datastructure

This commit is contained in:
Sunil Arora 2018-02-01 10:44:30 -08:00 committed by Antoine Pelisse
parent 1d83bdccea
commit 4a03e39222
6 changed files with 136 additions and 243 deletions

View File

@ -17,41 +17,13 @@ limitations under the License.
package commands package commands
import ( import (
"fmt"
"io" "io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
type addConfigMap struct {
// Name of configMap (required)
Name string
// FileSources to derive the configMap from (optional)
FileSources []string
// LiteralSources to derive the configMap from (optional)
LiteralSources []string
// EnvFileSource to derive the configMap from (optional)
EnvFileSource string
}
// validate validates required fields are set to support structured generation.
func (a *addConfigMap) Validate(args []string) error {
if len(args) != 1 {
return fmt.Errorf("name must be specified once")
}
a.Name = args[0]
if len(a.EnvFileSource) == 0 && len(a.FileSources) == 0 && len(a.LiteralSources) == 0 {
return fmt.Errorf("at least from-env-file, or from-file or from-literal must be set")
}
if len(a.EnvFileSource) > 0 && (len(a.FileSources) > 0 || len(a.LiteralSources) > 0) {
return fmt.Errorf("from-env-file cannot be combined with from-file or from-literal")
}
// TODO: Should we check if the path exists? if it's valid, if it's within the same (sub-)directory?
return nil
}
func NewCmdAddConfigMap(errOut io.Writer) *cobra.Command { func NewCmdAddConfigMap(errOut io.Writer) *cobra.Command {
var config addConfigMap var config dataConfig
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1]", Use: "configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1]",
Short: "Adds a configmap to your manifest file.", Short: "Adds a configmap to your manifest file.",

View File

@ -25,65 +25,3 @@ func TestNewAddConfigMapIsNotNil(t *testing.T) {
t.Fatal("NewCmdAddConfigMap shouldn't be nil") t.Fatal("NewCmdAddConfigMap shouldn't be nil")
} }
} }
func TestAddConfigValidation_NoName(t *testing.T) {
config := addConfigMap{}
if config.Validate([]string{}) == nil {
t.Fatal("Validation should fail if no name is specified")
}
}
func TestAddConfigValidation_MoreThanOneName(t *testing.T) {
config := addConfigMap{}
if config.Validate([]string{"name", "othername"}) == nil {
t.Fatal("Validation should fail if more than one name is specified")
}
}
func TestAddConfigValidation_Flags(t *testing.T) {
tests := []struct {
name string
config addConfigMap
shouldFail bool
}{
{
name: "env-file-source and literal are both set",
config: addConfigMap{
LiteralSources: []string{"one", "two"},
EnvFileSource: "three",
},
shouldFail: true,
},
{
name: "env-file-source and from-file are both set",
config: addConfigMap{
FileSources: []string{"one", "two"},
EnvFileSource: "three",
},
shouldFail: true,
},
{
name: "we don't have any option set",
config: addConfigMap{},
shouldFail: true,
},
{
name: "we have from-file and literal ",
config: addConfigMap{
LiteralSources: []string{"one", "two"},
FileSources: []string{"three", "four"},
},
shouldFail: false,
},
}
for _, test := range tests {
if test.config.Validate([]string{"name"}) == nil && test.shouldFail {
t.Fatalf("Validation should fail if %s", test.name)
} else if test.config.Validate([]string{"name"}) != nil && !test.shouldFail {
t.Fatalf("Validation should succeed if %s", test.name)
}
}
}

View File

@ -0,0 +1,49 @@
/*
Copyright 2018 The Kubernetes 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 commands
import (
"fmt"
)
// dataConfig encapsulates the options for add configmap/Secret commands.
type dataConfig struct {
// Name of configMap/Secret (required)
Name string
// FileSources to derive the configMap/Secret from (optional)
FileSources []string
// LiteralSources to derive the configMap/Secret from (optional)
LiteralSources []string
// EnvFileSource to derive the configMap/Secret from (optional)
EnvFileSource string
}
// Validate validates required fields are set to support structured generation.
func (a *dataConfig) Validate(args []string) error {
if len(args) != 1 {
return fmt.Errorf("name must be specified once")
}
a.Name = args[0]
if len(a.EnvFileSource) == 0 && len(a.FileSources) == 0 && len(a.LiteralSources) == 0 {
return fmt.Errorf("at least from-env-file, or from-file or from-literal must be set")
}
if len(a.EnvFileSource) > 0 && (len(a.FileSources) > 0 || len(a.LiteralSources) > 0) {
return fmt.Errorf("from-env-file cannot be combined with from-file or from-literal")
}
// TODO: Should we check if the path exists? if it's valid, if it's within the same (sub-)directory?
return nil
}

View File

@ -0,0 +1,83 @@
/*
Copyright 2018 The Kubernetes 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 commands
import (
"testing"
)
func TestDataConfigValidation_NoName(t *testing.T) {
config := dataConfig{}
if config.Validate([]string{}) == nil {
t.Fatal("Validation should fail if no name is specified")
}
}
func TestDataConfigValidation_MoreThanOneName(t *testing.T) {
config := dataConfig{}
if config.Validate([]string{"name", "othername"}) == nil {
t.Fatal("Validation should fail if more than one name is specified")
}
}
func TestDataConfigValidation_Flags(t *testing.T) {
tests := []struct {
name string
config dataConfig
shouldFail bool
}{
{
name: "env-file-source and literal are both set",
config: dataConfig{
LiteralSources: []string{"one", "two"},
EnvFileSource: "three",
},
shouldFail: true,
},
{
name: "env-file-source and from-file are both set",
config: dataConfig{
FileSources: []string{"one", "two"},
EnvFileSource: "three",
},
shouldFail: true,
},
{
name: "we don't have any option set",
config: dataConfig{},
shouldFail: true,
},
{
name: "we have from-file and literal ",
config: dataConfig{
LiteralSources: []string{"one", "two"},
FileSources: []string{"three", "four"},
},
shouldFail: false,
},
}
for _, test := range tests {
if test.config.Validate([]string{"name"}) == nil && test.shouldFail {
t.Fatalf("Validation should fail if %s", test.name)
} else if test.config.Validate([]string{"name"}) != nil && !test.shouldFail {
t.Fatalf("Validation should succeed if %s", test.name)
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2017 The Kubernetes Authors. Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -23,35 +23,8 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
type addGenericSecret struct {
// Name of secret (required)
Name string
// FileSources to derive the secret from (optional)
FileSources []string
// LiteralSources to derive the secret from (optional)
LiteralSources []string
// EnvFileSource to derive the secret from (optional)
EnvFileSource string
}
// Validate validates required fields are set to support structured generation.
func (a *addGenericSecret) Validate(args []string) error {
if len(args) != 1 {
return fmt.Errorf("name must be specified once")
}
a.Name = args[0]
if len(a.EnvFileSource) == 0 && len(a.FileSources) == 0 && len(a.LiteralSources) == 0 {
return fmt.Errorf("at least from-env-file, or from-file or from-literal must be set")
}
if len(a.EnvFileSource) > 0 && (len(a.FileSources) > 0 || len(a.LiteralSources) > 0) {
return fmt.Errorf("from-env-file cannot be combined with from-file or from-literal")
}
// TODO: Should we check if the path exists? if it's valid, if it's within the same (sub-)directory?
return nil
}
func newCmdAddSecretGeneric(errOut io.Writer) *cobra.Command { func newCmdAddSecretGeneric(errOut io.Writer) *cobra.Command {
var config addGenericSecret var config dataConfig
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1]", Use: "generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1]",
Short: "Adds a secret from a local file, directory or literal value.", Short: "Adds a secret from a local file, directory or literal value.",

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2017 The Kubernetes Authors. Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -25,125 +25,3 @@ func TestNewAddSecretIsNotNil(t *testing.T) {
t.Fatal("NewCmdAddSecret shouldn't be nil") t.Fatal("NewCmdAddSecret shouldn't be nil")
} }
} }
func TestAddGenericSecretValidation_NoName(t *testing.T) {
config := addGenericSecret{}
if config.Validate([]string{}) == nil {
t.Fatal("Validation should fail if no name is specified")
}
}
func TestAddGenericSecretValidation_MoreThanOneName(t *testing.T) {
config := addGenericSecret{}
if config.Validate([]string{"name", "othername"}) == nil {
t.Fatal("Validation should fail if more than one name is specified")
}
}
func TestAddGenericSecretValidation_Flags(t *testing.T) {
tests := []struct {
name string
config addGenericSecret
shouldFail bool
}{
{
name: "env-file-source and literal are both set",
config: addGenericSecret{
LiteralSources: []string{"one", "two"},
EnvFileSource: "three",
},
shouldFail: true,
},
{
name: "env-file-source and from-file are both set",
config: addGenericSecret{
FileSources: []string{"one", "two"},
EnvFileSource: "three",
},
shouldFail: true,
},
{
name: "we don't have any option set",
config: addGenericSecret{},
shouldFail: true,
},
{
name: "we have from-file and literal ",
config: addGenericSecret{
LiteralSources: []string{"one", "two"},
FileSources: []string{"three", "four"},
},
shouldFail: false,
},
}
for _, test := range tests {
if test.config.Validate([]string{"name"}) == nil && test.shouldFail {
t.Fatalf("Validation should fail if %s", test.name)
} else if test.config.Validate([]string{"name"}) != nil && !test.shouldFail {
t.Fatalf("Validation should succeed if %s", test.name)
}
}
}
func TestAddTLSSecretValidation_NoName(t *testing.T) {
config := addTLSSecret{}
if config.Validate([]string{}) == nil {
t.Fatal("Validation should fail if no name is specified")
}
}
func TestAddTLSSecretValidation_MoreThanOneName(t *testing.T) {
config := addTLSSecret{}
if config.Validate([]string{"name", "othername"}) == nil {
t.Fatal("Validation should fail if more than one name is specified")
}
}
func TestAddTLSSecretValidation_Flags(t *testing.T) {
tests := []struct {
name string
config addTLSSecret
shouldFail bool
}{
{
name: "cert and key are set",
config: addTLSSecret{
Cert: "cert",
Key: "key",
},
shouldFail: false,
},
{
name: "cert is set, but not key",
config: addTLSSecret{
Cert: "cert",
},
shouldFail: true,
},
{
name: "key is set, but not cert",
config: addTLSSecret{
Key: "key",
},
shouldFail: true,
},
{
name: "neither key nor cert is set",
config: addTLSSecret{},
shouldFail: true,
},
}
for _, test := range tests {
if test.config.Validate([]string{"name"}) == nil && test.shouldFail {
t.Fatalf("Validation should fail if %s", test.name)
} else if test.config.Validate([]string{"name"}) != nil && !test.shouldFail {
t.Fatalf("Validation should succeed if %s", test.name)
}
}
}