Merge pull request #54572 from ellenkorbes/ellenmakesamess

Automatic merge from submit-queue (batch tested with PRs 54572, 54686). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

kubectl partial env docs & examples

**What this PR does / why we need it**:

It adds documentation and examples to kubectl env.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: This PR partially addresses [#98](https://github.com/kubernetes/kubectl/issues/98).

**Special notes for your reviewer**:

This is a partial PR. I'm mostly looking for feedback as to whether I'm on the right track with this issue. Any feedback is appreciated. Thanks.

(This is my contribution to Outreachy's Kubernetes internship application.)

**Release note**:


```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2017-10-30 21:45:14 -07:00 committed by GitHub
commit f46f0efd31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 135 additions and 11 deletions

View File

@ -1,8 +1,9 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"env_parse.go",
"env_resolve.go",
],
@ -32,3 +33,10 @@ filegroup(
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["env_parse_test.go"],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/env",
library = ":go_default_library",
)

18
pkg/kubectl/cmd/util/env/doc.go vendored Normal file
View File

@ -0,0 +1,18 @@
/*
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 provides functions to incorporate environment variables into kubectl commands.
package env // import "k8s.io/kubernetes/pkg/kubectl/cmd/util/env"

View File

@ -28,7 +28,7 @@ import (
"k8s.io/kubernetes/pkg/api"
)
// Env returns an environment variable or a default value if not specified.
// Env returns an environment variable if not nil, or a default value.
func Env(key string, defaultValue string) string {
val := os.Getenv(key)
if len(val) == 0 {
@ -37,7 +37,7 @@ func Env(key string, defaultValue string) string {
return val
}
// GetEnv returns an environment value if specified
// GetEnv returns an environment value if not nil, and an ok boolean.
func GetEnv(key string) (string, bool) {
val := os.Getenv(key)
if len(val) == 0 {
@ -49,17 +49,18 @@ func GetEnv(key string) (string, bool) {
var argumentEnvironment = regexp.MustCompile("(?ms)^(.+)\\=(.*)$")
var validArgumentEnvironment = regexp.MustCompile("(?ms)^(\\w+)\\=(.*)$")
// IsEnvironmentArgument check str is env args
// IsEnvironmentArgument checks whether a string is an environment argument, that is, whether it matches the "anycharacters=anycharacters" pattern.
func IsEnvironmentArgument(s string) bool {
return argumentEnvironment.MatchString(s)
}
// IsValidEnvironmentArgument check str is valid env
// IsValidEnvironmentArgument checks whether a string is a valid environment argument, that is, whether it matches the "wordcharacters=anycharacters" pattern. Word characters can be letters, numbers, and underscores.
func IsValidEnvironmentArgument(s string) bool {
return validArgumentEnvironment.MatchString(s)
}
// SplitEnvironmentFromResources returns resources and envargs
// SplitEnvironmentFromResources separates resources from environment arguments.
// Resources must come first. Arguments may have the "DASH-" syntax.
func SplitEnvironmentFromResources(args []string) (resources, envArgs []string, ok bool) {
first := true
for _, s := range args {
@ -123,7 +124,8 @@ func parseIntoEnvVar(spec []string, defaultReader io.Reader, envVarType string)
return env, remove, nil
}
// ParseEnv parse env from reader
// ParseEnv parses the elements of the first argument looking for environment variables in key=value form and, if one of those values is "-", it also scans the reader.
// The same environment variable cannot be both modified and removed in the same command.
func ParseEnv(spec []string, defaultReader io.Reader) ([]api.EnvVar, []string, error) {
return parseIntoEnvVar(spec, defaultReader, "environment variable")
}

View File

@ -0,0 +1,96 @@
/*
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"
"io"
"os"
"strings"
)
func ExampleEnv_defaultValue() {
fmt.Println(Env("TESTENVVAR", "default"))
// Output: default
}
func ExampleEnv_variableExists() {
os.Setenv("TESTENVVAR", "test value")
defer os.Unsetenv("TESTENVVAR")
fmt.Println(Env("TESTENVVAR", "default"))
// Output: test value
}
func ExampleGetEnv_variableExists() {
os.Setenv("THISVAREXISTS", "value")
defer os.Unsetenv("THISVAREXISTS")
fmt.Println(GetEnv("THISVAREXISTS"))
// Output:
// value true
}
func ExampleGetEnv_variableDoesNotExist() {
fmt.Println(GetEnv("THISVARDOESNOTEXIST"))
// Output:
// false
}
func ExampleIsEnvironmentArgument_true() {
test := "returns=true"
fmt.Println(IsEnvironmentArgument(test))
// Output: true
}
func ExampleIsEnvironmentArgument_false() {
test := "returnsfalse"
fmt.Println(IsEnvironmentArgument(test))
// Output: false
}
func ExampleIsValidEnvironmentArgument_true() {
test := "wordcharacters=true"
fmt.Println(IsValidEnvironmentArgument(test))
// Output: true
}
func ExampleIsValidEnvironmentArgument_false() {
test := "not$word^characters=test"
fmt.Println(IsValidEnvironmentArgument(test))
// Output: false
}
func ExampleSplitEnvironmentFromResources() {
args := []string{`resource`, "ENV\\=ARG", `ONE\=MORE`, `DASH-`}
fmt.Println(SplitEnvironmentFromResources(args))
// Output: [resource] [ENV\=ARG ONE\=MORE DASH-] true
}
func ExampleParseEnv_good() {
r := strings.NewReader("FROM=READER")
ss := []string{"ENV=VARIABLE", "AND=ANOTHER", "REMOVE-", "-"}
fmt.Println(ParseEnv(ss, r))
// Output:
// [{ENV VARIABLE <nil>} {AND ANOTHER <nil>} {FROM READER <nil>}] [REMOVE] <nil>
}
func ExampleParseEnv_bad() {
var r io.Reader
bad := []string{"This not in the key=value format."}
fmt.Println(ParseEnv(bad, r))
// Output:
// [] [] environment variables must be of the form key=value and can only contain letters, numbers, and underscores
}

View File

@ -27,13 +27,13 @@ import (
"k8s.io/kubernetes/pkg/fieldpath"
)
// ResourceStore defines a new resource store data structure
// 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
// NewResourceStore returns a pointer to a new resource store data structure.
func NewResourceStore() *ResourceStore {
return &ResourceStore{
SecretStore: make(map[string]*api.Secret),
@ -86,7 +86,7 @@ func getResourceFieldRef(from *api.EnvVarSource, c *api.Container) (string, erro
return resource.ExtractContainerResourceValue(from.ResourceFieldRef, c)
}
// GetEnvVarRefValue returns the value referenced by the supplied envvarsource given the other supplied information
// 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)
@ -107,7 +107,7 @@ func GetEnvVarRefValue(kc clientset.Interface, ns string, store *ResourceStore,
return "", fmt.Errorf("invalid valueFrom")
}
// GetEnvVarRefString returns a text description of the supplied envvarsource
// GetEnvVarRefString returns a text description of whichever field is set within the supplied EnvVarSource argument.
func GetEnvVarRefString(from *api.EnvVarSource) string {
if from.ConfigMapKeyRef != nil {
return fmt.Sprintf("configmap %s, key %s", from.ConfigMapKeyRef.Name, from.ConfigMapKeyRef.Key)