Commit 4d5fc465 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #50998 from zjj2wry/set-env

Automatic merge from submit-queue (batch tested with PRs 51377, 46580, 50998, 51466, 49749) feat(#21648 )Add kubectl set env command. **What this PR does / why we need it**: #21648 Moved from OpenShift to Kubenetes. @kargakis @smarterclayton **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
parents 367cdb1a 991238bf
...@@ -95,8 +95,10 @@ docs/man/man1/kubectl-rollout-resume.1 ...@@ -95,8 +95,10 @@ docs/man/man1/kubectl-rollout-resume.1
docs/man/man1/kubectl-rollout-status.1 docs/man/man1/kubectl-rollout-status.1
docs/man/man1/kubectl-rollout-undo.1 docs/man/man1/kubectl-rollout-undo.1
docs/man/man1/kubectl-rollout.1 docs/man/man1/kubectl-rollout.1
docs/man/man1/kubectl-run-container.1
docs/man/man1/kubectl-run.1 docs/man/man1/kubectl-run.1
docs/man/man1/kubectl-scale.1 docs/man/man1/kubectl-scale.1
docs/man/man1/kubectl-set-env.1
docs/man/man1/kubectl-set-image.1 docs/man/man1/kubectl-set-image.1
docs/man/man1/kubectl-set-resources.1 docs/man/man1/kubectl-set-resources.1
docs/man/man1/kubectl-set-selector.1 docs/man/man1/kubectl-set-selector.1
...@@ -191,6 +193,7 @@ docs/user-guide/kubectl/kubectl_rollout_undo.md ...@@ -191,6 +193,7 @@ docs/user-guide/kubectl/kubectl_rollout_undo.md
docs/user-guide/kubectl/kubectl_run.md docs/user-guide/kubectl/kubectl_run.md
docs/user-guide/kubectl/kubectl_scale.md docs/user-guide/kubectl/kubectl_scale.md
docs/user-guide/kubectl/kubectl_set.md docs/user-guide/kubectl/kubectl_set.md
docs/user-guide/kubectl/kubectl_set_env.md
docs/user-guide/kubectl/kubectl_set_image.md docs/user-guide/kubectl/kubectl_set_image.md
docs/user-guide/kubectl/kubectl_set_resources.md docs/user-guide/kubectl/kubectl_set_resources.md
docs/user-guide/kubectl/kubectl_set_selector.md docs/user-guide/kubectl/kubectl_set_selector.md
...@@ -236,6 +239,7 @@ docs/yaml/kubectl/kubectl_proxy.yaml ...@@ -236,6 +239,7 @@ docs/yaml/kubectl/kubectl_proxy.yaml
docs/yaml/kubectl/kubectl_replace.yaml docs/yaml/kubectl/kubectl_replace.yaml
docs/yaml/kubectl/kubectl_rolling-update.yaml docs/yaml/kubectl/kubectl_rolling-update.yaml
docs/yaml/kubectl/kubectl_rollout.yaml docs/yaml/kubectl/kubectl_rollout.yaml
docs/yaml/kubectl/kubectl_run-container.yaml
docs/yaml/kubectl/kubectl_run.yaml docs/yaml/kubectl/kubectl_run.yaml
docs/yaml/kubectl/kubectl_scale.yaml docs/yaml/kubectl/kubectl_scale.yaml
docs/yaml/kubectl/kubectl_set.yaml docs/yaml/kubectl/kubectl_set.yaml
......
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.
...@@ -2860,6 +2860,31 @@ run_deployment_tests() { ...@@ -2860,6 +2860,31 @@ run_deployment_tests() {
# Clean up # Clean up
kubectl delete deployment nginx-deployment "${kube_flags[@]}" kubectl delete deployment nginx-deployment "${kube_flags[@]}"
### Set env of a deployment
# Pre-condition: no deployment exists
kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" ''
# Create a deployment
kubectl create -f hack/testdata/deployment-multicontainer.yaml "${kube_flags[@]}"
kubectl create -f hack/testdata/configmap.yaml "${kube_flags[@]}"
kubectl create -f hack/testdata/secret.yaml "${kube_flags[@]}"
kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" 'nginx-deployment:'
kube::test::get_object_assert configmap "{{range.items}}{{$id_field}}:{{end}}" 'test-set-env-config:'
kube::test::get_object_assert secret "{{range.items}}{{$id_field}}:{{end}}" 'test-set-env-secret:'
# Set env of deployments for all container
kubectl set env deployment nginx-deployment env=prod "${kube_flags[@]}"
# Set env of deployments for specific container
kubectl set env deployment nginx-deployment env=prod -c=nginx "${kube_flags[@]}"
# Set env of deployments by configmap
kubectl set env deployment nginx-deployment --from=configmap/test-set-env-config "${kube_flags[@]}"
# Set env of deployments by secret
kubectl set env deployment nginx-deployment --from=secret/test-set-env-secret "${kube_flags[@]}"
# Remove specific env of deployment
kubectl set env deployment nginx-deployment env-
# Clean up
kubectl delete deployment nginx-deployment "${kube_flags[@]}"
kubectl delete configmap test-set-env-config "${kube_flags[@]}"
kubectl delete secret test-set-env-secret "${kube_flags[@]}"
set +o nounset set +o nounset
set +o errexit set +o errexit
} }
......
apiVersion: v1
data:
key-1: value-1
key-2: value-2
kind: ConfigMap
metadata:
name: test-set-env-config
\ No newline at end of file
apiVersion: v1
kind: Secret
metadata:
name: test-set-env-secret
type: Opaque
data:
password: dmFsdWUtMg0K
username: dmFsdWUtMQ0K
\ No newline at end of file
...@@ -285,7 +285,8 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob ...@@ -285,7 +285,8 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
NewCmdCreate(f, out, err), NewCmdCreate(f, out, err),
NewCmdExposeService(f, out), NewCmdExposeService(f, out),
NewCmdRun(f, in, out, err), NewCmdRun(f, in, out, err),
set.NewCmdSet(f, out, err), set.NewCmdSet(f, in, out, err),
deprecatedAlias("run-container", NewCmdRun(f, in, out, err)),
}, },
}, },
{ {
......
...@@ -9,6 +9,7 @@ go_library( ...@@ -9,6 +9,7 @@ go_library(
srcs = [ srcs = [
"helper.go", "helper.go",
"set.go", "set.go",
"set_env.go",
"set_image.go", "set_image.go",
"set_resources.go", "set_resources.go",
"set_selector.go", "set_selector.go",
...@@ -22,6 +23,7 @@ go_library( ...@@ -22,6 +23,7 @@ go_library(
"//pkg/kubectl:go_default_library", "//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/templates:go_default_library", "//pkg/kubectl/cmd/templates:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/env:go_default_library",
"//pkg/kubectl/resource:go_default_library", "//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/util/i18n:go_default_library", "//pkg/kubectl/util/i18n:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
...@@ -40,6 +42,7 @@ go_library( ...@@ -40,6 +42,7 @@ go_library(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"set_env_test.go",
"set_image_test.go", "set_image_test.go",
"set_resources_test.go", "set_resources_test.go",
"set_selector_test.go", "set_selector_test.go",
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/strategicpatch" "k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
...@@ -158,3 +159,37 @@ func CalculatePatches(infos []*resource.Info, encoder runtime.Encoder, mutateFn ...@@ -158,3 +159,37 @@ func CalculatePatches(infos []*resource.Info, encoder runtime.Encoder, mutateFn
} }
return patches return patches
} }
func findEnv(env []api.EnvVar, name string) (api.EnvVar, bool) {
for _, e := range env {
if e.Name == name {
return e, true
}
}
return api.EnvVar{}, false
}
func updateEnv(existing []api.EnvVar, env []api.EnvVar, remove []string) []api.EnvVar {
out := []api.EnvVar{}
covered := sets.NewString(remove...)
for _, e := range existing {
if covered.Has(e.Name) {
continue
}
newer, ok := findEnv(env, e.Name)
if ok {
covered.Insert(e.Name)
out = append(out, newer)
continue
}
out = append(out, e)
}
for _, e := range env {
if covered.Has(e.Name) {
continue
}
covered.Insert(e.Name)
out = append(out, e)
}
return out
}
...@@ -32,7 +32,7 @@ var ( ...@@ -32,7 +32,7 @@ var (
These commands help you make changes to existing application resources.`) These commands help you make changes to existing application resources.`)
) )
func NewCmdSet(f cmdutil.Factory, out, err io.Writer) *cobra.Command { func NewCmdSet(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "set SUBCOMMAND", Use: "set SUBCOMMAND",
Short: i18n.T("Set specific features on objects"), Short: i18n.T("Set specific features on objects"),
...@@ -46,5 +46,7 @@ func NewCmdSet(f cmdutil.Factory, out, err io.Writer) *cobra.Command { ...@@ -46,5 +46,7 @@ func NewCmdSet(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
cmd.AddCommand(NewCmdSelector(f, out)) cmd.AddCommand(NewCmdSelector(f, out))
cmd.AddCommand(NewCmdSubject(f, out, err)) cmd.AddCommand(NewCmdSubject(f, out, err))
cmd.AddCommand(NewCmdServiceAccount(f, out, err)) cmd.AddCommand(NewCmdServiceAccount(f, out, err))
cmd.AddCommand(NewCmdEnv(f, in, out, err))
return cmd return cmd
} }
/*
Copyright 2017 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 (
"bytes"
"net/http"
"strings"
"testing"
"k8s.io/apimachinery/pkg/runtime"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/printers"
"os"
)
func TestSetEnvLocal(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf.Client = &fake.RESTClient{
APIRegistry: api.Registry,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
return nil, nil
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdEnv(f, os.Stdin, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := EnvOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../examples/storage/cassandra/cassandra-controller.yaml"}},
Out: buf,
Local: true}
err := opts.Complete(f, cmd, []string{"env=prod"})
if err == nil {
err = opts.RunEnv(f)
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !strings.Contains(buf.String(), "replicationcontrollers/cassandra") {
t.Errorf("did not set env: %s", buf.String())
}
}
...@@ -23,13 +23,14 @@ import ( ...@@ -23,13 +23,14 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
clientcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" clientcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"os"
) )
func TestLocalAndDryRunFlags(t *testing.T) { func TestLocalAndDryRunFlags(t *testing.T) {
out := &bytes.Buffer{} out := &bytes.Buffer{}
errout := &bytes.Buffer{} errout := &bytes.Buffer{}
f := clientcmdutil.NewFactory(nil) f := clientcmdutil.NewFactory(nil)
setCmd := NewCmdSet(f, out, errout) setCmd := NewCmdSet(f, os.Stdin, out, errout)
ensureLocalAndDryRunFlagsOnChildren(t, setCmd, "") ensureLocalAndDryRunFlagsOnChildren(t, setCmd, "")
} }
......
...@@ -142,6 +142,7 @@ filegroup( ...@@ -142,6 +142,7 @@ filegroup(
srcs = [ srcs = [
":package-srcs", ":package-srcs",
"//pkg/kubectl/cmd/util/editor:all-srcs", "//pkg/kubectl/cmd/util/editor:all-srcs",
"//pkg/kubectl/cmd/util/env:all-srcs",
"//pkg/kubectl/cmd/util/jsonmerge:all-srcs", "//pkg/kubectl/cmd/util/jsonmerge:all-srcs",
"//pkg/kubectl/cmd/util/openapi:all-srcs", "//pkg/kubectl/cmd/util/openapi:all-srcs",
"//pkg/kubectl/cmd/util/sanity:all-srcs", "//pkg/kubectl/cmd/util/sanity:all-srcs",
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"env_parse.go",
"env_resolve.go",
],
visibility = ["//visibility:public"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/resource:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/fieldpath:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
Copyright 2017 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 env
import (
"bufio"
"fmt"
"io"
"os"
"regexp"
"strings"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/api"
)
// Env returns an environment variable or a default value if not specified.
func Env(key string, defaultValue string) string {
val := os.Getenv(key)
if len(val) == 0 {
return defaultValue
}
return val
}
// GetEnv returns an environment value if specified
func GetEnv(key string) (string, bool) {
val := os.Getenv(key)
if len(val) == 0 {
return "", false
}
return val, true
}
var argumentEnvironment = regexp.MustCompile("(?ms)^(.+)\\=(.*)$")
var validArgumentEnvironment = regexp.MustCompile("(?ms)^(\\w+)\\=(.*)$")
// IsEnvironmentArgument check str is env args
func IsEnvironmentArgument(s string) bool {
return argumentEnvironment.MatchString(s)
}
// IsValidEnvironmentArgument check str is valid env
func IsValidEnvironmentArgument(s string) bool {
return validArgumentEnvironment.MatchString(s)
}
// SplitEnvironmentFromResources returns resources and envargs
func SplitEnvironmentFromResources(args []string) (resources, envArgs []string, ok bool) {
first := true
for _, s := range args {
// this method also has to understand env removal syntax, i.e. KEY-
isEnv := IsEnvironmentArgument(s) || strings.HasSuffix(s, "-")
switch {
case first && isEnv:
first = false
fallthrough
case !first && isEnv:
envArgs = append(envArgs, s)
case first && !isEnv:
resources = append(resources, s)
case !first && !isEnv:
return nil, nil, false
}
}
return resources, envArgs, true
}
// parseIntoEnvVar parses the list of key-value pairs into kubernetes EnvVar.
// envVarType is for making errors more specific to user intentions.
func parseIntoEnvVar(spec []string, defaultReader io.Reader, envVarType string) ([]api.EnvVar, []string, error) {
env := []api.EnvVar{}
exists := sets.NewString()
var remove []string
for _, envSpec := range spec {
switch {
case !IsValidEnvironmentArgument(envSpec) && !strings.HasSuffix(envSpec, "-"):
return nil, nil, fmt.Errorf("%ss must be of the form key=value and can only contain letters, numbers, and underscores", envVarType)
case envSpec == "-":
if defaultReader == nil {
return nil, nil, fmt.Errorf("when '-' is used, STDIN must be open")
}
fileEnv, err := readEnv(defaultReader, envVarType)
if err != nil {
return nil, nil, err
}
env = append(env, fileEnv...)
case strings.Index(envSpec, "=") != -1:
parts := strings.SplitN(envSpec, "=", 2)
if len(parts) != 2 {
return nil, nil, fmt.Errorf("invalid %s: %v", envVarType, envSpec)
}
exists.Insert(parts[0])
env = append(env, api.EnvVar{
Name: parts[0],
Value: parts[1],
})
case strings.HasSuffix(envSpec, "-"):
remove = append(remove, envSpec[:len(envSpec)-1])
default:
return nil, nil, fmt.Errorf("unknown %s: %v", envVarType, envSpec)
}
}
for _, removeLabel := range remove {
if _, found := exists[removeLabel]; found {
return nil, nil, fmt.Errorf("can not both modify and remove the same %s in the same command", envVarType)
}
}
return env, remove, nil
}
// ParseEnv parse env from reader
func ParseEnv(spec []string, defaultReader io.Reader) ([]api.EnvVar, []string, error) {
return parseIntoEnvVar(spec, defaultReader, "environment variable")
}
func readEnv(r io.Reader, envVarType string) ([]api.EnvVar, error) {
env := []api.EnvVar{}
scanner := bufio.NewScanner(r)
for scanner.Scan() {
envSpec := scanner.Text()
if pos := strings.Index(envSpec, "#"); pos != -1 {
envSpec = envSpec[:pos]
}
if strings.Index(envSpec, "=") != -1 {
parts := strings.SplitN(envSpec, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid %s: %v", envVarType, envSpec)
}
env = append(env, api.EnvVar{
Name: parts[0],
Value: parts[1],
})
}
}
if err := scanner.Err(); err != nil && err != io.EOF {
return nil, err
}
return env, nil
}
/*
Copyright 2017 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 env
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/fieldpath"
)
// ResourceStore defines a new resource store data structure
type ResourceStore struct {
SecretStore map[string]*api.Secret
ConfigMapStore map[string]*api.ConfigMap
}
// NewResourceStore returns a pointer to a new resource store data structure
func NewResourceStore() *ResourceStore {
return &ResourceStore{
SecretStore: make(map[string]*api.Secret),
ConfigMapStore: make(map[string]*api.ConfigMap),
}
}
// getSecretRefValue returns the value of a secret in the supplied namespace
func getSecretRefValue(client clientset.Interface, namespace string, store *ResourceStore, secretSelector *api.SecretKeySelector) (string, error) {
secret, ok := store.SecretStore[secretSelector.Name]
if !ok {
var err error
secret, err = client.Core().Secrets(namespace).Get(secretSelector.Name, metav1.GetOptions{})
if err != nil {
return "", err
}
store.SecretStore[secretSelector.Name] = secret
}
if data, ok := secret.Data[secretSelector.Key]; ok {
return string(data), nil
}
return "", fmt.Errorf("key %s not found in secret %s", secretSelector.Key, secretSelector.Name)
}
// getConfigMapRefValue returns the value of a configmap in the supplied namespace
func getConfigMapRefValue(client clientset.Interface, namespace string, store *ResourceStore, configMapSelector *api.ConfigMapKeySelector) (string, error) {
configMap, ok := store.ConfigMapStore[configMapSelector.Name]
if !ok {
var err error
configMap, err = client.Core().ConfigMaps(namespace).Get(configMapSelector.Name, metav1.GetOptions{})
if err != nil {
return "", err
}
store.ConfigMapStore[configMapSelector.Name] = configMap
}
if data, ok := configMap.Data[configMapSelector.Key]; ok {
return string(data), nil
}
return "", fmt.Errorf("key %s not found in config map %s", configMapSelector.Key, configMapSelector.Name)
}
// getFieldRef returns the value of the supplied path in the given object
func getFieldRef(obj runtime.Object, from *api.EnvVarSource) (string, error) {
return fieldpath.ExtractFieldPathAsString(obj, from.FieldRef.FieldPath)
}
// getResourceFieldRef returns the value of a resource in the given container
func getResourceFieldRef(from *api.EnvVarSource, c *api.Container) (string, error) {
return resource.ExtractContainerResourceValue(from.ResourceFieldRef, c)
}
// GetEnvVarRefValue returns the value referenced by the supplied envvarsource given the other supplied information
func GetEnvVarRefValue(kc clientset.Interface, ns string, store *ResourceStore, from *api.EnvVarSource, obj runtime.Object, c *api.Container) (string, error) {
if from.SecretKeyRef != nil {
return getSecretRefValue(kc, ns, store, from.SecretKeyRef)
}
if from.ConfigMapKeyRef != nil {
return getConfigMapRefValue(kc, ns, store, from.ConfigMapKeyRef)
}
if from.FieldRef != nil {
return getFieldRef(obj, from)
}
if from.ResourceFieldRef != nil {
return getResourceFieldRef(from, c)
}
return "", fmt.Errorf("invalid valueFrom")
}
// GetEnvVarRefString returns a text description of the supplied envvarsource
func GetEnvVarRefString(from *api.EnvVarSource) string {
if from.ConfigMapKeyRef != nil {
return fmt.Sprintf("configmap %s, key %s", from.ConfigMapKeyRef.Name, from.ConfigMapKeyRef.Key)
}
if from.SecretKeyRef != nil {
return fmt.Sprintf("secret %s, key %s", from.SecretKeyRef.Name, from.SecretKeyRef.Key)
}
if from.FieldRef != nil {
return fmt.Sprintf("field path %s", from.FieldRef.FieldPath)
}
if from.ResourceFieldRef != nil {
containerPrefix := ""
if from.ResourceFieldRef.ContainerName != "" {
containerPrefix = fmt.Sprintf("%s/", from.ResourceFieldRef.ContainerName)
}
return fmt.Sprintf("resource field %s%s", containerPrefix, from.ResourceFieldRef.Resource)
}
return "invalid valueFrom"
}
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