Merge pull request #556 from zoncoen/name-suffix-2

Add nameSuffix field to kustomization.yaml
This commit is contained in:
k8s-ci-robot
2018-11-20 08:50:22 -08:00
committed by GitHub
11 changed files with 186 additions and 12 deletions

View File

@@ -36,6 +36,9 @@ func NewCmdEdit(fsys fs.FileSystem, v ifc.Validator, kf ifc.KunstructuredFactory
# Sets the nameprefix field
kustomize edit set nameprefix <prefix-value>
# Sets the namesuffix field
kustomize edit set namesuffix <suffix-value>
`,
Args: cobra.MinimumNArgs(1),
}

View File

@@ -31,12 +31,16 @@ func NewCmdSet(fsys fs.FileSystem, v ifc.Validator) *cobra.Command {
Example: `
# Sets the nameprefix field
kustomize edit set nameprefix <prefix-value>
# Sets the namesuffix field
kustomize edit set namesuffix <suffix-value>
`,
Args: cobra.MinimumNArgs(1),
}
c.AddCommand(
newCmdSetNamePrefix(fsys),
newCmdSetNameSuffix(fsys),
newCmdSetNamespace(fsys, v),
newCmdSetImageTag(fsys),
)

View File

@@ -0,0 +1,86 @@
/*
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 set
import (
"errors"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/pkg/commands/kustfile"
"sigs.k8s.io/kustomize/pkg/fs"
)
type setNameSuffixOptions struct {
suffix string
}
// newCmdSetNameSuffix sets the value of the nameSuffix field in the kustomization.
func newCmdSetNameSuffix(fsys fs.FileSystem) *cobra.Command {
var o setNameSuffixOptions
cmd := &cobra.Command{
Use: "namesuffix",
Short: "Sets the value of the nameSuffix field in the kustomization file.",
Example: `
The command
set namesuffix -- -acme
will add the field "nameSuffix: -acme" to the kustomization file if it doesn't exist,
and overwrite the value with "-acme" if the field does exist.
`,
RunE: func(cmd *cobra.Command, args []string) error {
err := o.Validate(args)
if err != nil {
return err
}
err = o.Complete(cmd, args)
if err != nil {
return err
}
return o.RunSetNameSuffix(fsys)
},
}
return cmd
}
// Validate validates setNameSuffix command.
func (o *setNameSuffixOptions) Validate(args []string) error {
if len(args) != 1 {
return errors.New("must specify exactly one suffix value")
}
// TODO: add further validation on the value.
o.suffix = args[0]
return nil
}
// Complete completes setNameSuffix command.
func (o *setNameSuffixOptions) Complete(cmd *cobra.Command, args []string) error {
return nil
}
// RunSetNameSuffix runs setNameSuffix command (does real work).
func (o *setNameSuffixOptions) RunSetNameSuffix(fSys fs.FileSystem) error {
mf, err := kustfile.NewKustomizationFile(fSys)
if err != nil {
return err
}
m, err := mf.Read()
if err != nil {
return err
}
m.NameSuffix = o.suffix
return mf.Write(m)
}

View File

@@ -0,0 +1,60 @@
/*
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 set
import (
"strings"
"testing"
"sigs.k8s.io/kustomize/pkg/fs"
)
const (
goodSuffixValue = "-acme"
)
func TestSetNameSuffixHappyPath(t *testing.T) {
fakeFS := fs.MakeFakeFS()
fakeFS.WriteTestKustomization()
cmd := newCmdSetNameSuffix(fakeFS)
args := []string{goodSuffixValue}
err := cmd.RunE(cmd, args)
if err != nil {
t.Errorf("unexpected cmd error: %v", err)
}
content, err := fakeFS.ReadTestKustomization()
if err != nil {
t.Errorf("unexpected read error: %v", err)
}
if !strings.Contains(string(content), goodSuffixValue) {
t.Errorf("expected suffix value in kustomization file")
}
}
func TestSetNameSuffixNoArgs(t *testing.T) {
fakeFS := fs.MakeFakeFS()
cmd := newCmdSetNameSuffix(fakeFS)
err := cmd.Execute()
if err == nil {
t.Errorf("expected error: %v", err)
}
if err.Error() != "must specify exactly one suffix value" {
t.Errorf("incorrect error: %v", err.Error())
}
}

View File

@@ -54,6 +54,7 @@ func determineFieldOrder() []string {
"Resources",
"Bases",
"NamePrefix",
"NameSuffix",
"Namespace",
"Crds",
"CommonLabels",

View File

@@ -33,6 +33,7 @@ func TestFieldOrder(t *testing.T) {
"Resources",
"Bases",
"NamePrefix",
"NameSuffix",
"Namespace",
"Crds",
"CommonLabels",
@@ -86,6 +87,7 @@ func TestWriteAndRead(t *testing.T) {
func TestDeprecationOfPatches(t *testing.T) {
hasDeprecatedFields := []byte(`
namePrefix: acme
nameSuffix: emca
patches:
- alice
patchesStrategicMerge:
@@ -104,6 +106,9 @@ patchesStrategicMerge:
if k.NamePrefix != "acme" {
t.Fatalf("Unexpected name prefix")
}
if k.NameSuffix != "emca" {
t.Fatalf("Unexpected name suffix")
}
if len(k.Patches) > 0 {
t.Fatalf("Expected nothing in Patches.")
}

View File

@@ -19,9 +19,10 @@ package fs
import (
"fmt"
"path/filepath"
"sigs.k8s.io/kustomize/pkg/constants"
"sort"
"strings"
"sigs.k8s.io/kustomize/pkg/constants"
)
var _ FileSystem = &fakeFs{}
@@ -40,6 +41,7 @@ func MakeFakeFS() *fakeFs {
// kustomizationContent is used in tests.
const kustomizationContent = `namePrefix: some-prefix
nameSuffix: some-suffix
# Labels to add to all objects and selectors.
# These labels would also be used to form the selector for apply --prune
# Named differently than “labels” to avoid confusion with metadata for this object

View File

@@ -17,6 +17,7 @@ limitations under the License.
package resid
import (
"fmt"
"strings"
"sigs.k8s.io/kustomize/pkg/gvk"
@@ -134,6 +135,13 @@ func (n ResId) Name() string {
return n.name
}
// NameWithPrefixSuffix returns resource name with prefix and suffix.
func (n ResId) NameWithPrefixSuffix() string {
prefix := strings.Join(n.prefixList(), "")
suffix := strings.Join(n.suffixList(), "")
return fmt.Sprintf("%s%s%s", prefix, n.name, suffix)
}
// Prefix returns name prefix.
func (n ResId) Prefix() string {
return n.prefix

View File

@@ -296,7 +296,7 @@ func (kt *KustTarget) newTransformer(patches []*resource.Resource) (transformers
string(kt.kustomization.Namespace), kt.tConfig.NameSpace))
t, err = transformers.NewNamePrefixSuffixTransformer(
string(kt.kustomization.NamePrefix),
"", // TODO(zoncoen): pass the name suffix
string(kt.kustomization.NameSuffix),
kt.tConfig.NamePrefix,
)
if err != nil {

View File

@@ -38,6 +38,7 @@ import (
const (
kustomizationContent1 = `
namePrefix: foo-
nameSuffix: -bar
namespace: ns1
commonLabels:
app: nginx
@@ -130,12 +131,12 @@ var ns = gvk.Gvk{Version: "v1", Kind: "Namespace"}
func TestResources1(t *testing.T) {
expected := resmap.ResMap{
resid.NewResIdWithPrefixNamespace(deploy, "dply1", "foo-", "ns1"): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(deploy, "dply1", "foo-", "-bar", "ns1"): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "foo-dply1",
"name": "foo-dply1-bar",
"namespace": "ns1",
"labels": map[string]interface{}{
"app": "nginx",
@@ -163,12 +164,12 @@ func TestResources1(t *testing.T) {
},
},
}),
resid.NewResIdWithPrefixNamespace(cmap, "literalConfigMap", "foo-", "ns1"): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(cmap, "literalConfigMap", "foo-", "-bar", "ns1"): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "foo-literalConfigMap-mc92bgcbh5",
"name": "foo-literalConfigMap-bar-8d2dkb8k24",
"namespace": "ns1",
"labels": map[string]interface{}{
"app": "nginx",
@@ -182,12 +183,12 @@ func TestResources1(t *testing.T) {
"DB_PASSWORD": "somepw",
},
}).SetBehavior(ifc.BehaviorCreate),
resid.NewResIdWithPrefixNamespace(secret, "secret", "foo-", "ns1"): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(secret, "secret", "foo-", "-bar", "ns1"): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "Secret",
"metadata": map[string]interface{}{
"name": "foo-secret-877fcfhgt5",
"name": "foo-secret-bar-9btc7bt4kb",
"namespace": "ns1",
"labels": map[string]interface{}{
"app": "nginx",
@@ -202,12 +203,12 @@ func TestResources1(t *testing.T) {
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
},
}).SetBehavior(ifc.BehaviorCreate),
resid.NewResIdWithPrefixNamespace(ns, "ns1", "foo-", ""): rf.RF().FromMap(
resid.NewResIdWithPrefixSuffixNamespace(ns, "ns1", "foo-", "-bar", ""): rf.RF().FromMap(
map[string]interface{}{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": map[string]interface{}{
"name": "foo-ns1",
"name": "foo-ns1-bar",
"labels": map[string]interface{}{
"app": "nginx",
},
@@ -268,8 +269,8 @@ func TestDisableNameSuffixHash(t *testing.T) {
}
for id, r := range actual {
if !strings.HasSuffix(r.GetName(), id.Name()) {
t.Fatalf("unexpected hash was added to %s: %s", id.Name(), r.GetName())
if r.GetName() != id.NameWithPrefixSuffix() {
t.Errorf("unexpected hash was added to %s: %s", id.NameWithPrefixSuffix(), r.GetName())
}
}
}

View File

@@ -42,6 +42,10 @@ type Kustomization struct {
// file including generated configmaps and secrets.
NamePrefix string `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
// NameSuffix will suffix the names of all resources mentioned in the kustomization
// file including generated configmaps and secrets.
NameSuffix string `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
// Namespace to add to all objects.
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`