11
vendor/k8s.io/cli-runtime/pkg/genericclioptions/builder_flags.go
generated
vendored
11
vendor/k8s.io/cli-runtime/pkg/genericclioptions/builder_flags.go
generated
vendored
@@ -52,6 +52,9 @@ func NewResourceBuilderFlags() *ResourceBuilderFlags {
|
||||
}
|
||||
}
|
||||
|
||||
// WithFile sets the FileNameFlags.
|
||||
// If recurse is set, it will process directory recursively. Useful when you want to manage related manifests
|
||||
// organized within the same directory.
|
||||
func (o *ResourceBuilderFlags) WithFile(recurse bool, files ...string) *ResourceBuilderFlags {
|
||||
o.FileNameFlags = &FileNameFlags{
|
||||
Usage: "identifying the resource.",
|
||||
@@ -62,41 +65,49 @@ func (o *ResourceBuilderFlags) WithFile(recurse bool, files ...string) *Resource
|
||||
return o
|
||||
}
|
||||
|
||||
// WithLabelSelector sets the LabelSelector flag
|
||||
func (o *ResourceBuilderFlags) WithLabelSelector(selector string) *ResourceBuilderFlags {
|
||||
o.LabelSelector = &selector
|
||||
return o
|
||||
}
|
||||
|
||||
// WithFieldSelector sets the FieldSelector flag
|
||||
func (o *ResourceBuilderFlags) WithFieldSelector(selector string) *ResourceBuilderFlags {
|
||||
o.FieldSelector = &selector
|
||||
return o
|
||||
}
|
||||
|
||||
// WithAllNamespaces sets the AllNamespaces flag
|
||||
func (o *ResourceBuilderFlags) WithAllNamespaces(defaultVal bool) *ResourceBuilderFlags {
|
||||
o.AllNamespaces = &defaultVal
|
||||
return o
|
||||
}
|
||||
|
||||
// WithAll sets the All flag
|
||||
func (o *ResourceBuilderFlags) WithAll(defaultVal bool) *ResourceBuilderFlags {
|
||||
o.All = &defaultVal
|
||||
return o
|
||||
}
|
||||
|
||||
// WithLocal sets the Local flag
|
||||
func (o *ResourceBuilderFlags) WithLocal(defaultVal bool) *ResourceBuilderFlags {
|
||||
o.Local = &defaultVal
|
||||
return o
|
||||
}
|
||||
|
||||
// WithScheme sets the Scheme flag
|
||||
func (o *ResourceBuilderFlags) WithScheme(scheme *runtime.Scheme) *ResourceBuilderFlags {
|
||||
o.Scheme = scheme
|
||||
return o
|
||||
}
|
||||
|
||||
// WithLatest sets the Latest flag
|
||||
func (o *ResourceBuilderFlags) WithLatest() *ResourceBuilderFlags {
|
||||
o.Latest = true
|
||||
return o
|
||||
}
|
||||
|
||||
// StopOnError sets the StopOnFirstError flag
|
||||
func (o *ResourceBuilderFlags) StopOnError() *ResourceBuilderFlags {
|
||||
o.StopOnFirstError = true
|
||||
return o
|
||||
|
||||
2
vendor/k8s.io/cli-runtime/pkg/genericclioptions/builder_flags_fake.go
generated
vendored
2
vendor/k8s.io/cli-runtime/pkg/genericclioptions/builder_flags_fake.go
generated
vendored
@@ -20,7 +20,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
)
|
||||
|
||||
// NewSimpleResourceFinder builds a super simple ResourceFinder that just iterates over the objects you provided
|
||||
// NewSimpleFakeResourceFinder builds a super simple ResourceFinder that just iterates over the objects you provided
|
||||
func NewSimpleFakeResourceFinder(infos ...*resource.Info) ResourceFinder {
|
||||
return &fakeResourceFinder{
|
||||
Infos: infos,
|
||||
|
||||
72
vendor/k8s.io/cli-runtime/pkg/genericclioptions/client_config.go
generated
vendored
Normal file
72
vendor/k8s.io/cli-runtime/pkg/genericclioptions/client_config.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2020 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 genericclioptions
|
||||
|
||||
import (
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrEmptyConfig is the error message to be displayed if the configuration info is missing or incomplete
|
||||
ErrEmptyConfig = clientcmd.NewEmptyConfigError(`Missing or incomplete configuration info. Please point to an existing, complete config file:
|
||||
|
||||
|
||||
1. Via the command-line flag --kubeconfig
|
||||
2. Via the KUBECONFIG environment variable
|
||||
3. In your home directory as ~/.kube/config
|
||||
|
||||
To view or setup config directly use the 'config' command.`)
|
||||
)
|
||||
|
||||
var _ = clientcmd.ClientConfig(&clientConfig{})
|
||||
|
||||
type clientConfig struct {
|
||||
defaultClientConfig clientcmd.ClientConfig
|
||||
}
|
||||
|
||||
func (c *clientConfig) RawConfig() (clientcmdapi.Config, error) {
|
||||
config, err := c.defaultClientConfig.RawConfig()
|
||||
// replace client-go's ErrEmptyConfig error with our custom, more verbose version
|
||||
if clientcmd.IsEmptyConfig(err) {
|
||||
return config, ErrEmptyConfig
|
||||
}
|
||||
return config, err
|
||||
}
|
||||
|
||||
func (c *clientConfig) ClientConfig() (*restclient.Config, error) {
|
||||
config, err := c.defaultClientConfig.ClientConfig()
|
||||
// replace client-go's ErrEmptyConfig error with our custom, more verbose version
|
||||
if clientcmd.IsEmptyConfig(err) {
|
||||
return config, ErrEmptyConfig
|
||||
}
|
||||
return config, err
|
||||
}
|
||||
|
||||
func (c *clientConfig) Namespace() (string, bool, error) {
|
||||
namespace, ok, err := c.defaultClientConfig.Namespace()
|
||||
// replace client-go's ErrEmptyConfig error with our custom, more verbose version
|
||||
if clientcmd.IsEmptyConfig(err) {
|
||||
return namespace, ok, ErrEmptyConfig
|
||||
}
|
||||
return namespace, ok, err
|
||||
}
|
||||
|
||||
func (c *clientConfig) ConfigAccess() clientcmd.ConfigAccess {
|
||||
return c.defaultClientConfig.ConfigAccess()
|
||||
}
|
||||
79
vendor/k8s.io/cli-runtime/pkg/genericclioptions/command_headers.go
generated
vendored
Normal file
79
vendor/k8s.io/cli-runtime/pkg/genericclioptions/command_headers.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2021 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 genericclioptions
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
kubectlCommandHeader = "X-Kubectl-Command"
|
||||
kubectlSessionHeader = "X-Kubectl-Session"
|
||||
)
|
||||
|
||||
// CommandHeaderRoundTripper adds a layer around the standard
|
||||
// round tripper to add Request headers before delegation. Implements
|
||||
// the go standard library "http.RoundTripper" interface.
|
||||
type CommandHeaderRoundTripper struct {
|
||||
Delegate http.RoundTripper
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// CommandHeaderRoundTripper adds Request headers before delegating to standard
|
||||
// round tripper. These headers are kubectl command headers which
|
||||
// detail the kubectl command. See SIG CLI KEP 859:
|
||||
// https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/859-kubectl-headers
|
||||
func (c *CommandHeaderRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
for header, value := range c.Headers {
|
||||
req.Header.Set(header, value)
|
||||
}
|
||||
return c.Delegate.RoundTrip(req)
|
||||
}
|
||||
|
||||
// ParseCommandHeaders fills in a map of X-Headers into the CommandHeaderRoundTripper. These
|
||||
// headers are then filled into each request. For details on X-Headers see:
|
||||
// https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/859-kubectl-headers
|
||||
// Each call overwrites the previously parsed command headers (not additive).
|
||||
// TODO(seans3): Parse/add flags removing PII from flag values.
|
||||
func (c *CommandHeaderRoundTripper) ParseCommandHeaders(cmd *cobra.Command, args []string) {
|
||||
if cmd == nil {
|
||||
return
|
||||
}
|
||||
// Overwrites previously parsed command headers (headers not additive).
|
||||
c.Headers = map[string]string{}
|
||||
// Session identifier to aggregate multiple Requests from single kubectl command.
|
||||
uid := uuid.New().String()
|
||||
c.Headers[kubectlSessionHeader] = uid
|
||||
// Iterate up the hierarchy of commands from the leaf command to create
|
||||
// the full command string. Example: kubectl create secret generic
|
||||
cmdStrs := []string{}
|
||||
for cmd.HasParent() {
|
||||
parent := cmd.Parent()
|
||||
currName := strings.TrimSpace(cmd.Name())
|
||||
cmdStrs = append([]string{currName}, cmdStrs...)
|
||||
cmd = parent
|
||||
}
|
||||
currName := strings.TrimSpace(cmd.Name())
|
||||
cmdStrs = append([]string{currName}, cmdStrs...)
|
||||
if len(cmdStrs) > 0 {
|
||||
c.Headers[kubectlCommandHeader] = strings.Join(cmdStrs, " ")
|
||||
}
|
||||
}
|
||||
67
vendor/k8s.io/cli-runtime/pkg/genericclioptions/config_flags.go
generated
vendored
67
vendor/k8s.io/cli-runtime/pkg/genericclioptions/config_flags.go
generated
vendored
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package genericclioptions
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@@ -53,19 +52,11 @@ const (
|
||||
flagUsername = "username"
|
||||
flagPassword = "password"
|
||||
flagTimeout = "request-timeout"
|
||||
flagHTTPCacheDir = "cache-dir"
|
||||
flagCacheDir = "cache-dir"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultCacheDir = filepath.Join(homedir.HomeDir(), ".kube", "http-cache")
|
||||
|
||||
ErrEmptyConfig = errors.New(`Missing or incomplete configuration info. Please point to an existing, complete config file:
|
||||
|
||||
1. Via the command-line flag --kubeconfig
|
||||
2. Via the KUBECONFIG environment variable
|
||||
3. In your home directory as ~/.kube/config
|
||||
|
||||
To view or setup config directly use the 'config' command.`)
|
||||
defaultCacheDir = filepath.Join(homedir.HomeDir(), ".kube", "cache")
|
||||
)
|
||||
|
||||
// RESTClientGetter is an interface that the ConfigFlags describe to provide an easier way to mock for commands
|
||||
@@ -107,6 +98,9 @@ type ConfigFlags struct {
|
||||
Username *string
|
||||
Password *string
|
||||
Timeout *string
|
||||
// If non-nil, wrap config function can transform the Config
|
||||
// before it is returned in ToRESTConfig function.
|
||||
WrapConfigFn func(*rest.Config) *rest.Config
|
||||
|
||||
clientConfig clientcmd.ClientConfig
|
||||
lock sync.Mutex
|
||||
@@ -114,19 +108,25 @@ type ConfigFlags struct {
|
||||
// propagate the config to the places that need it, rather than
|
||||
// loading the config multiple times
|
||||
usePersistentConfig bool
|
||||
// Allows increasing burst used for discovery, this is useful
|
||||
// in clusters with many registered resources
|
||||
discoveryBurst int
|
||||
}
|
||||
|
||||
// ToRESTConfig implements RESTClientGetter.
|
||||
// Returns a REST client configuration based on a provided path
|
||||
// to a .kubeconfig file, loading rules, and config flag overrides.
|
||||
// Expects the AddFlags method to have been called.
|
||||
// Expects the AddFlags method to have been called. If WrapConfigFn
|
||||
// is non-nil this function can transform config before return.
|
||||
func (f *ConfigFlags) ToRESTConfig() (*rest.Config, error) {
|
||||
config, err := f.ToRawKubeConfigLoader().ClientConfig()
|
||||
// replace client-go's ErrEmptyConfig error with our custom, more verbose version
|
||||
if clientcmd.IsEmptyConfig(err) {
|
||||
return nil, ErrEmptyConfig
|
||||
c, err := f.ToRawKubeConfigLoader().ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return config, err
|
||||
if f.WrapConfigFn != nil {
|
||||
return f.WrapConfigFn(c), nil
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ToRawKubeConfigLoader binds config flag values to config overrides
|
||||
@@ -206,16 +206,11 @@ func (f *ConfigFlags) toRawKubeConfigLoader() clientcmd.ClientConfig {
|
||||
overrides.Timeout = *f.Timeout
|
||||
}
|
||||
|
||||
var clientConfig clientcmd.ClientConfig
|
||||
|
||||
// we only have an interactive prompt when a password is allowed
|
||||
if f.Password == nil {
|
||||
clientConfig = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)
|
||||
} else {
|
||||
clientConfig = clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, os.Stdin)
|
||||
return &clientConfig{clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)}
|
||||
}
|
||||
|
||||
return clientConfig
|
||||
return &clientConfig{clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, os.Stdin)}
|
||||
}
|
||||
|
||||
// toRawKubePersistentConfigLoader binds config flag values to config overrides
|
||||
@@ -243,16 +238,18 @@ func (f *ConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, e
|
||||
// The more groups you have, the more discovery requests you need to make.
|
||||
// given 25 groups (our groups + a few custom resources) with one-ish version each, discovery needs to make 50 requests
|
||||
// double it just so we don't end up here again for a while. This config is only used for discovery.
|
||||
config.Burst = 100
|
||||
config.Burst = f.discoveryBurst
|
||||
|
||||
cacheDir := defaultCacheDir
|
||||
|
||||
// retrieve a user-provided value for the "cache-dir"
|
||||
// defaulting to ~/.kube/http-cache if no user-value is given.
|
||||
httpCacheDir := defaultCacheDir
|
||||
// override httpCacheDir and discoveryCacheDir if user-value is given.
|
||||
if f.CacheDir != nil {
|
||||
httpCacheDir = *f.CacheDir
|
||||
cacheDir = *f.CacheDir
|
||||
}
|
||||
httpCacheDir := filepath.Join(cacheDir, "http")
|
||||
discoveryCacheDir := computeDiscoverCacheDir(filepath.Join(cacheDir, "discovery"), config.Host)
|
||||
|
||||
discoveryCacheDir := computeDiscoverCacheDir(filepath.Join(homedir.HomeDir(), ".kube", "cache", "discovery"), config.Host)
|
||||
return diskcached.NewCachedDiscoveryClientForConfig(config, discoveryCacheDir, httpCacheDir, time.Duration(10*time.Minute))
|
||||
}
|
||||
|
||||
@@ -274,7 +271,7 @@ func (f *ConfigFlags) AddFlags(flags *pflag.FlagSet) {
|
||||
flags.StringVar(f.KubeConfig, "kubeconfig", *f.KubeConfig, "Path to the kubeconfig file to use for CLI requests.")
|
||||
}
|
||||
if f.CacheDir != nil {
|
||||
flags.StringVar(f.CacheDir, flagHTTPCacheDir, *f.CacheDir, "Default HTTP cache directory")
|
||||
flags.StringVar(f.CacheDir, flagCacheDir, *f.CacheDir, "Default cache directory")
|
||||
}
|
||||
|
||||
// add config options
|
||||
@@ -337,6 +334,12 @@ func (f *ConfigFlags) WithDeprecatedPasswordFlag() *ConfigFlags {
|
||||
return f
|
||||
}
|
||||
|
||||
// WithDiscoveryBurst sets the RESTClient burst for discovery.
|
||||
func (f *ConfigFlags) WithDiscoveryBurst(discoveryBurst int) *ConfigFlags {
|
||||
f.discoveryBurst = discoveryBurst
|
||||
return f
|
||||
}
|
||||
|
||||
// NewConfigFlags returns ConfigFlags with default values set
|
||||
func NewConfigFlags(usePersistentConfig bool) *ConfigFlags {
|
||||
impersonateGroup := []string{}
|
||||
@@ -362,6 +365,10 @@ func NewConfigFlags(usePersistentConfig bool) *ConfigFlags {
|
||||
ImpersonateGroup: &impersonateGroup,
|
||||
|
||||
usePersistentConfig: usePersistentConfig,
|
||||
// The more groups you have, the more discovery requests you need to make.
|
||||
// given 25 groups (our groups + a few custom resources) with one-ish version each, discovery needs to make 50 requests
|
||||
// double it just so we don't end up here again for a while. This config is only used for discovery.
|
||||
discoveryBurst: 100,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
19
vendor/k8s.io/cli-runtime/pkg/genericclioptions/config_flags_fake.go
generated
vendored
19
vendor/k8s.io/cli-runtime/pkg/genericclioptions/config_flags_fake.go
generated
vendored
@@ -27,12 +27,16 @@ import (
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
// TestConfigFlags contains clientConfig struct
|
||||
// and interfaces that implements RESTClientGetter
|
||||
type TestConfigFlags struct {
|
||||
clientConfig clientcmd.ClientConfig
|
||||
discoveryClient discovery.CachedDiscoveryInterface
|
||||
restMapper meta.RESTMapper
|
||||
}
|
||||
|
||||
// ToRawKubeConfigLoader implements RESTClientGetter
|
||||
// Returns a clientconfig if it's set
|
||||
func (f *TestConfigFlags) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
||||
if f.clientConfig == nil {
|
||||
panic("attempt to obtain a test RawKubeConfigLoader with no clientConfig specified")
|
||||
@@ -40,14 +44,22 @@ func (f *TestConfigFlags) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
||||
return f.clientConfig
|
||||
}
|
||||
|
||||
// ToRESTConfig implements RESTClientGetter.
|
||||
// Returns a REST client configuration based on a provided path
|
||||
// to a .kubeconfig file, loading rules, and config flag overrides.
|
||||
// Expects the AddFlags method to have been called.
|
||||
func (f *TestConfigFlags) ToRESTConfig() (*rest.Config, error) {
|
||||
return f.ToRawKubeConfigLoader().ClientConfig()
|
||||
}
|
||||
|
||||
// ToDiscoveryClient implements RESTClientGetter.
|
||||
// Returns a CachedDiscoveryInterface
|
||||
func (f *TestConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
|
||||
return f.discoveryClient, nil
|
||||
}
|
||||
|
||||
// ToRESTMapper implements RESTClientGetter.
|
||||
// Returns a mapper.
|
||||
func (f *TestConfigFlags) ToRESTMapper() (meta.RESTMapper, error) {
|
||||
if f.restMapper != nil {
|
||||
return f.restMapper, nil
|
||||
@@ -60,21 +72,25 @@ func (f *TestConfigFlags) ToRESTMapper() (meta.RESTMapper, error) {
|
||||
return nil, fmt.Errorf("no restmapper")
|
||||
}
|
||||
|
||||
// WithClientConfig sets the clientConfig flag
|
||||
func (f *TestConfigFlags) WithClientConfig(clientConfig clientcmd.ClientConfig) *TestConfigFlags {
|
||||
f.clientConfig = clientConfig
|
||||
return f
|
||||
}
|
||||
|
||||
// WithRESTMapper sets the restMapper flag
|
||||
func (f *TestConfigFlags) WithRESTMapper(mapper meta.RESTMapper) *TestConfigFlags {
|
||||
f.restMapper = mapper
|
||||
return f
|
||||
}
|
||||
|
||||
// WithDiscoveryClient sets the discoveryClient flag
|
||||
func (f *TestConfigFlags) WithDiscoveryClient(c discovery.CachedDiscoveryInterface) *TestConfigFlags {
|
||||
f.discoveryClient = c
|
||||
return f
|
||||
}
|
||||
|
||||
// WithNamespace sets the clientConfig flag by modifying delagate and namespace
|
||||
func (f *TestConfigFlags) WithNamespace(ns string) *TestConfigFlags {
|
||||
if f.clientConfig == nil {
|
||||
panic("attempt to obtain a test RawKubeConfigLoader with no clientConfig specified")
|
||||
@@ -86,6 +102,7 @@ func (f *TestConfigFlags) WithNamespace(ns string) *TestConfigFlags {
|
||||
return f
|
||||
}
|
||||
|
||||
// NewTestConfigFlags builds a TestConfigFlags struct to test ConfigFlags
|
||||
func NewTestConfigFlags() *TestConfigFlags {
|
||||
return &TestConfigFlags{}
|
||||
}
|
||||
@@ -96,7 +113,7 @@ type namespacedClientConfig struct {
|
||||
}
|
||||
|
||||
func (c *namespacedClientConfig) Namespace() (string, bool, error) {
|
||||
return c.namespace, false, nil
|
||||
return c.namespace, len(c.namespace) > 0, nil
|
||||
}
|
||||
|
||||
func (c *namespacedClientConfig) RawConfig() (clientcmdapi.Config, error) {
|
||||
|
||||
2
vendor/k8s.io/cli-runtime/pkg/genericclioptions/doc.go
generated
vendored
2
vendor/k8s.io/cli-runtime/pkg/genericclioptions/doc.go
generated
vendored
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package genericclioptions contains flags which can be added to you command, bound, completed, and produce
|
||||
// Package genericclioptions contains flags which can be added to your command, bound, completed, and produce
|
||||
// useful helper functions. Nothing in this package can depend on kube/kube
|
||||
package genericclioptions // import "k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
|
||||
3
vendor/k8s.io/cli-runtime/pkg/genericclioptions/filename_flags.go
generated
vendored
3
vendor/k8s.io/cli-runtime/pkg/genericclioptions/filename_flags.go
generated
vendored
@@ -25,6 +25,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
)
|
||||
|
||||
// FileNameFlags are flags for processing files.
|
||||
// Usage of this struct by itself is discouraged.
|
||||
// These flags are composed by ResourceBuilderFlags
|
||||
// which should be used instead.
|
||||
@@ -36,6 +37,7 @@ type FileNameFlags struct {
|
||||
Recursive *bool
|
||||
}
|
||||
|
||||
// ToOptions creates a new FileNameOptions struct and sets FilenameOptions based on FileNameflags
|
||||
func (o *FileNameFlags) ToOptions() resource.FilenameOptions {
|
||||
options := resource.FilenameOptions{}
|
||||
|
||||
@@ -56,6 +58,7 @@ func (o *FileNameFlags) ToOptions() resource.FilenameOptions {
|
||||
return options
|
||||
}
|
||||
|
||||
// AddFlags binds file name flags to a given flagset
|
||||
func (o *FileNameFlags) AddFlags(flags *pflag.FlagSet) {
|
||||
if o == nil {
|
||||
return
|
||||
|
||||
13
vendor/k8s.io/cli-runtime/pkg/genericclioptions/json_yaml_flags.go
generated
vendored
13
vendor/k8s.io/cli-runtime/pkg/genericclioptions/json_yaml_flags.go
generated
vendored
@@ -24,6 +24,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
)
|
||||
|
||||
// AllowedFormats returns slice of string of allowed JSONYaml printing format
|
||||
func (f *JSONYamlPrintFlags) AllowedFormats() []string {
|
||||
if f == nil {
|
||||
return []string{}
|
||||
@@ -35,6 +36,7 @@ func (f *JSONYamlPrintFlags) AllowedFormats() []string {
|
||||
// Given the following flag values, a printer can be requested that knows
|
||||
// how to handle printing based on these values.
|
||||
type JSONYamlPrintFlags struct {
|
||||
showManagedFields bool
|
||||
}
|
||||
|
||||
// ToPrinter receives an outputFormat and returns a printer capable of
|
||||
@@ -54,12 +56,21 @@ func (f *JSONYamlPrintFlags) ToPrinter(outputFormat string) (printers.ResourcePr
|
||||
return nil, NoCompatiblePrinterError{OutputFormat: &outputFormat, AllowedFormats: f.AllowedFormats()}
|
||||
}
|
||||
|
||||
if !f.showManagedFields {
|
||||
printer = &printers.OmitManagedFieldsPrinter{Delegate: printer}
|
||||
}
|
||||
return printer, nil
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
// flags related to JSON or Yaml printing to it
|
||||
func (f *JSONYamlPrintFlags) AddFlags(c *cobra.Command) {}
|
||||
func (f *JSONYamlPrintFlags) AddFlags(c *cobra.Command) {
|
||||
if f == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.Flags().BoolVar(&f.showManagedFields, "show-managed-fields", f.showManagedFields, "If true, keep the managedFields when printing objects in JSON or YAML format.")
|
||||
}
|
||||
|
||||
// NewJSONYamlPrintFlags returns flags associated with
|
||||
// yaml or json printing, with default values set.
|
||||
|
||||
15
vendor/k8s.io/cli-runtime/pkg/genericclioptions/jsonpath_flags.go
generated
vendored
15
vendor/k8s.io/cli-runtime/pkg/genericclioptions/jsonpath_flags.go
generated
vendored
@@ -31,8 +31,9 @@ import (
|
||||
// this allows a user to specify a template format value
|
||||
// as --output=jsonpath=
|
||||
var jsonFormats = map[string]bool{
|
||||
"jsonpath": true,
|
||||
"jsonpath-file": true,
|
||||
"jsonpath": true,
|
||||
"jsonpath-file": true,
|
||||
"jsonpath-as-json": true,
|
||||
}
|
||||
|
||||
// JSONPathPrintFlags provides default flags necessary for template printing.
|
||||
@@ -45,6 +46,7 @@ type JSONPathPrintFlags struct {
|
||||
TemplateArgument *string
|
||||
}
|
||||
|
||||
// AllowedFormats returns slice of string of allowed JSONPath printing format
|
||||
func (f *JSONPathPrintFlags) AllowedFormats() []string {
|
||||
formats := make([]string, 0, len(jsonFormats))
|
||||
for format := range jsonFormats {
|
||||
@@ -88,7 +90,7 @@ func (f *JSONPathPrintFlags) ToPrinter(templateFormat string) (printers.Resource
|
||||
if templateFormat == "jsonpath-file" {
|
||||
data, err := ioutil.ReadFile(templateValue)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading --template %s, %v\n", templateValue, err)
|
||||
return nil, fmt.Errorf("error reading --template %s, %v", templateValue, err)
|
||||
}
|
||||
|
||||
templateValue = string(data)
|
||||
@@ -96,7 +98,7 @@ func (f *JSONPathPrintFlags) ToPrinter(templateFormat string) (printers.Resource
|
||||
|
||||
p, err := printers.NewJSONPathPrinter(templateValue)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing jsonpath %s, %v\n", templateValue, err)
|
||||
return nil, fmt.Errorf("error parsing jsonpath %s, %v", templateValue, err)
|
||||
}
|
||||
|
||||
allowMissingKeys := true
|
||||
@@ -105,6 +107,11 @@ func (f *JSONPathPrintFlags) ToPrinter(templateFormat string) (printers.Resource
|
||||
}
|
||||
|
||||
p.AllowMissingKeys(allowMissingKeys)
|
||||
|
||||
if templateFormat == "jsonpath-as-json" {
|
||||
p.EnableJSONOutput(true)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
|
||||
5
vendor/k8s.io/cli-runtime/pkg/genericclioptions/kube_template_flags.go
generated
vendored
5
vendor/k8s.io/cli-runtime/pkg/genericclioptions/kube_template_flags.go
generated
vendored
@@ -33,6 +33,7 @@ type KubeTemplatePrintFlags struct {
|
||||
TemplateArgument *string
|
||||
}
|
||||
|
||||
// AllowedFormats returns slice of string of allowed GoTemplete and JSONPathPrint printing formats
|
||||
func (f *KubeTemplatePrintFlags) AllowedFormats() []string {
|
||||
if f == nil {
|
||||
return []string{}
|
||||
@@ -40,6 +41,10 @@ func (f *KubeTemplatePrintFlags) AllowedFormats() []string {
|
||||
return append(f.GoTemplatePrintFlags.AllowedFormats(), f.JSONPathPrintFlags.AllowedFormats()...)
|
||||
}
|
||||
|
||||
// ToPrinter receives an outputFormat and returns a printer capable of
|
||||
// handling --template printing.
|
||||
// Returns false if the specified outputFormat does not match a supported format.
|
||||
// Supported Format types can be found in pkg/printers/printers.go
|
||||
func (f *KubeTemplatePrintFlags) ToPrinter(outputFormat string) (printers.ResourcePrinter, error) {
|
||||
if f == nil {
|
||||
return nil, NoCompatiblePrinterError{}
|
||||
|
||||
2
vendor/k8s.io/cli-runtime/pkg/genericclioptions/name_flags.go
generated
vendored
2
vendor/k8s.io/cli-runtime/pkg/genericclioptions/name_flags.go
generated
vendored
@@ -35,11 +35,13 @@ type NamePrintFlags struct {
|
||||
Operation string
|
||||
}
|
||||
|
||||
// Complete sets NamePrintFlags operation flag from sucessTemplate
|
||||
func (f *NamePrintFlags) Complete(successTemplate string) error {
|
||||
f.Operation = fmt.Sprintf(successTemplate, f.Operation)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllowedFormats returns slice of string of allowed Name printing format
|
||||
func (f *NamePrintFlags) AllowedFormats() []string {
|
||||
if f == nil {
|
||||
return []string{}
|
||||
|
||||
13
vendor/k8s.io/cli-runtime/pkg/genericclioptions/print_flags.go
generated
vendored
13
vendor/k8s.io/cli-runtime/pkg/genericclioptions/print_flags.go
generated
vendored
@@ -27,6 +27,8 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
)
|
||||
|
||||
// NoCompatiblePrinterError is a struct that contains error information.
|
||||
// It will be constructed when a invalid printing format is provided
|
||||
type NoCompatiblePrinterError struct {
|
||||
OutputFormat *string
|
||||
AllowedFormats []string
|
||||
@@ -43,6 +45,8 @@ func (e NoCompatiblePrinterError) Error() string {
|
||||
return fmt.Sprintf("unable to match a printer suitable for the output format %q, allowed formats are: %s", output, strings.Join(e.AllowedFormats, ","))
|
||||
}
|
||||
|
||||
// IsNoCompatiblePrinterError returns true if it is a not a compatible printer
|
||||
// otherwise it will return false
|
||||
func IsNoCompatiblePrinterError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
@@ -69,10 +73,12 @@ type PrintFlags struct {
|
||||
OutputFlagSpecified func() bool
|
||||
}
|
||||
|
||||
// Complete sets NamePrintFlags operation flag from sucessTemplate
|
||||
func (f *PrintFlags) Complete(successTemplate string) error {
|
||||
return f.NamePrintFlags.Complete(successTemplate)
|
||||
}
|
||||
|
||||
// AllowedFormats returns slice of string of allowed JSONYaml/Name/Template printing format
|
||||
func (f *PrintFlags) AllowedFormats() []string {
|
||||
ret := []string{}
|
||||
ret = append(ret, f.JSONYamlPrintFlags.AllowedFormats()...)
|
||||
@@ -81,6 +87,10 @@ func (f *PrintFlags) AllowedFormats() []string {
|
||||
return ret
|
||||
}
|
||||
|
||||
// ToPrinter returns a printer capable of
|
||||
// handling --output or --template printing.
|
||||
// Returns false if the specified outputFormat does not match a supported format.
|
||||
// Supported format types can be found in pkg/printers/printers.go
|
||||
func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
|
||||
outputFormat := ""
|
||||
if f.OutputFormat != nil {
|
||||
@@ -118,6 +128,8 @@ func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
|
||||
return nil, NoCompatiblePrinterError{OutputFormat: f.OutputFormat, AllowedFormats: f.AllowedFormats()}
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
// flags related to JSON/Yaml/Name/Template printing to it
|
||||
func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
|
||||
f.JSONYamlPrintFlags.AddFlags(cmd)
|
||||
f.NamePrintFlags.AddFlags(cmd)
|
||||
@@ -145,6 +157,7 @@ func (f *PrintFlags) WithTypeSetter(scheme *runtime.Scheme) *PrintFlags {
|
||||
return f
|
||||
}
|
||||
|
||||
// NewPrintFlags returns a default *PrintFlags
|
||||
func NewPrintFlags(operation string) *PrintFlags {
|
||||
outputFormat := ""
|
||||
|
||||
|
||||
3
vendor/k8s.io/cli-runtime/pkg/genericclioptions/record_flags.go
generated
vendored
3
vendor/k8s.io/cli-runtime/pkg/genericclioptions/record_flags.go
generated
vendored
@@ -21,7 +21,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
@@ -74,6 +74,7 @@ func (f *RecordFlags) Complete(cmd *cobra.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompleteWithChangeCause alters changeCause value with a new cause
|
||||
func (f *RecordFlags) CompleteWithChangeCause(cause string) error {
|
||||
if f == nil {
|
||||
return nil
|
||||
|
||||
5
vendor/k8s.io/cli-runtime/pkg/genericclioptions/template_flags.go
generated
vendored
5
vendor/k8s.io/cli-runtime/pkg/genericclioptions/template_flags.go
generated
vendored
@@ -47,6 +47,7 @@ type GoTemplatePrintFlags struct {
|
||||
TemplateArgument *string
|
||||
}
|
||||
|
||||
// AllowedFormats returns slice of string of allowed GoTemplatePrint printing format
|
||||
func (f *GoTemplatePrintFlags) AllowedFormats() []string {
|
||||
formats := make([]string, 0, len(templateFormats))
|
||||
for format := range templateFormats {
|
||||
@@ -90,7 +91,7 @@ func (f *GoTemplatePrintFlags) ToPrinter(templateFormat string) (printers.Resour
|
||||
if templateFormat == "templatefile" || templateFormat == "go-template-file" {
|
||||
data, err := ioutil.ReadFile(templateValue)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading --template %s, %v\n", templateValue, err)
|
||||
return nil, fmt.Errorf("error reading --template %s, %v", templateValue, err)
|
||||
}
|
||||
|
||||
templateValue = string(data)
|
||||
@@ -98,7 +99,7 @@ func (f *GoTemplatePrintFlags) ToPrinter(templateFormat string) (printers.Resour
|
||||
|
||||
p, err := printers.NewGoTemplatePrinter([]byte(templateValue))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing template %s, %v\n", templateValue, err)
|
||||
return nil, fmt.Errorf("error parsing template %s, %v", templateValue, err)
|
||||
}
|
||||
|
||||
allowMissingKeys := true
|
||||
|
||||
32
vendor/k8s.io/cli-runtime/pkg/kustomize/builder.go
generated
vendored
32
vendor/k8s.io/cli-runtime/pkg/kustomize/builder.go
generated
vendored
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 kustomize
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps"
|
||||
"sigs.k8s.io/kustomize/pkg/commands/build"
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
)
|
||||
|
||||
// RunKustomizeBuild runs kustomize build given a filesystem and a path
|
||||
func RunKustomizeBuild(out io.Writer, fSys fs.FileSystem, path string) error {
|
||||
f := k8sdeps.NewFactory()
|
||||
o := build.NewOptions(path, "")
|
||||
return o.RunBuild(out, fSys, f.ResmapF, f.TransformerF)
|
||||
}
|
||||
125
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret/configmapfactory.go
generated
vendored
125
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret/configmapfactory.go
generated
vendored
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
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 configmapandsecret generates configmaps and secrets per generator rules.
|
||||
package configmapandsecret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kv"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// ConfigMapFactory makes ConfigMaps.
|
||||
type ConfigMapFactory struct {
|
||||
ldr ifc.Loader
|
||||
}
|
||||
|
||||
// NewConfigMapFactory returns a new ConfigMapFactory.
|
||||
func NewConfigMapFactory(l ifc.Loader) *ConfigMapFactory {
|
||||
return &ConfigMapFactory{ldr: l}
|
||||
}
|
||||
|
||||
func (f *ConfigMapFactory) makeFreshConfigMap(
|
||||
args *types.ConfigMapArgs) *corev1.ConfigMap {
|
||||
cm := &corev1.ConfigMap{}
|
||||
cm.APIVersion = "v1"
|
||||
cm.Kind = "ConfigMap"
|
||||
cm.Name = args.Name
|
||||
cm.Namespace = args.Namespace
|
||||
cm.Data = map[string]string{}
|
||||
return cm
|
||||
}
|
||||
|
||||
// MakeConfigMap returns a new ConfigMap, or nil and an error.
|
||||
func (f *ConfigMapFactory) MakeConfigMap(
|
||||
args *types.ConfigMapArgs, options *types.GeneratorOptions) (*corev1.ConfigMap, error) {
|
||||
var all []kv.Pair
|
||||
var err error
|
||||
cm := f.makeFreshConfigMap(args)
|
||||
|
||||
pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"env source file: %s",
|
||||
args.EnvSource))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromLiteralSources(args.LiteralSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"literal sources %v", args.LiteralSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"file sources: %v", args.FileSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
for _, p := range all {
|
||||
err = addKvToConfigMap(cm, p.Key, p.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if options != nil {
|
||||
cm.SetLabels(options.Labels)
|
||||
cm.SetAnnotations(options.Annotations)
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
// addKvToConfigMap adds the given key and data to the given config map.
|
||||
// Error if key invalid, or already exists.
|
||||
func addKvToConfigMap(configMap *corev1.ConfigMap, keyName, data string) error {
|
||||
// Note, the rules for ConfigMap keys are the exact same as the ones for SecretKeys.
|
||||
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
|
||||
return fmt.Errorf("%q is not a valid key name for a ConfigMap: %s", keyName, strings.Join(errs, ";"))
|
||||
}
|
||||
|
||||
keyExistsErrorMsg := "cannot add key %s, another key by that name already exists: %v"
|
||||
|
||||
// If the configmap data contains byte sequences that are all in the UTF-8
|
||||
// range, we will write it to .Data
|
||||
if utf8.Valid([]byte(data)) {
|
||||
if _, entryExists := configMap.Data[keyName]; entryExists {
|
||||
return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.Data)
|
||||
}
|
||||
configMap.Data[keyName] = data
|
||||
return nil
|
||||
}
|
||||
|
||||
// otherwise, it's BinaryData
|
||||
if configMap.BinaryData == nil {
|
||||
configMap.BinaryData = map[string][]byte{}
|
||||
}
|
||||
if _, entryExists := configMap.BinaryData[keyName]; entryExists {
|
||||
return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.BinaryData)
|
||||
}
|
||||
configMap.BinaryData[keyName] = []byte(data)
|
||||
return nil
|
||||
}
|
||||
107
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret/kv.go
generated
vendored
107
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret/kv.go
generated
vendored
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 configmapandsecret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kv"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) {
|
||||
var kvs []kv.Pair
|
||||
for _, s := range sources {
|
||||
k, v, err := parseLiteralSource(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kvs = append(kvs, kv.Pair{Key: k, Value: v})
|
||||
}
|
||||
return kvs, nil
|
||||
}
|
||||
|
||||
func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.Pair, error) {
|
||||
var kvs []kv.Pair
|
||||
for _, s := range sources {
|
||||
k, fPath, err := parseFileSource(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err := ldr.Load(fPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kvs = append(kvs, kv.Pair{Key: k, Value: string(content)})
|
||||
}
|
||||
return kvs, nil
|
||||
}
|
||||
|
||||
func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kv.Pair, error) {
|
||||
if path == "" {
|
||||
return nil, nil
|
||||
}
|
||||
content, err := l.Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kv.KeyValuesFromLines(content)
|
||||
}
|
||||
|
||||
// parseFileSource parses the source given.
|
||||
//
|
||||
// Acceptable formats include:
|
||||
// 1. source-path: the basename will become the key name
|
||||
// 2. source-name=source-path: the source-name will become the key name and
|
||||
// source-path is the path to the key file.
|
||||
//
|
||||
// Key names cannot include '='.
|
||||
func parseFileSource(source string) (keyName, filePath string, err error) {
|
||||
numSeparators := strings.Count(source, "=")
|
||||
switch {
|
||||
case numSeparators == 0:
|
||||
return path.Base(source), source, nil
|
||||
case numSeparators == 1 && strings.HasPrefix(source, "="):
|
||||
return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "="))
|
||||
case numSeparators == 1 && strings.HasSuffix(source, "="):
|
||||
return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "="))
|
||||
case numSeparators > 1:
|
||||
return "", "", errors.New("key names or file paths cannot contain '='")
|
||||
default:
|
||||
components := strings.Split(source, "=")
|
||||
return components[0], components[1], nil
|
||||
}
|
||||
}
|
||||
|
||||
// parseLiteralSource parses the source key=val pair into its component pieces.
|
||||
// This functionality is distinguished from strings.SplitN(source, "=", 2) since
|
||||
// it returns an error in the case of empty keys, values, or a missing equals sign.
|
||||
func parseLiteralSource(source string) (keyName, value string, err error) {
|
||||
// leading equal is invalid
|
||||
if strings.Index(source, "=") == 0 {
|
||||
return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source)
|
||||
}
|
||||
// split after the first equal (so values can have the = character)
|
||||
items := strings.SplitN(source, "=", 2)
|
||||
if len(items) != 2 {
|
||||
return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source)
|
||||
}
|
||||
return items[0], strings.Trim(items[1], "\"'"), nil
|
||||
}
|
||||
106
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret/secretfactory.go
generated
vendored
106
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret/secretfactory.go
generated
vendored
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
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 configmapandsecret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kv"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// SecretFactory makes Secrets.
|
||||
type SecretFactory struct {
|
||||
ldr ifc.Loader
|
||||
}
|
||||
|
||||
// NewSecretFactory returns a new SecretFactory.
|
||||
func NewSecretFactory(ldr ifc.Loader) *SecretFactory {
|
||||
return &SecretFactory{ldr: ldr}
|
||||
}
|
||||
|
||||
func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret {
|
||||
s := &corev1.Secret{}
|
||||
s.APIVersion = "v1"
|
||||
s.Kind = "Secret"
|
||||
s.Name = args.Name
|
||||
s.Namespace = args.Namespace
|
||||
s.Type = corev1.SecretType(args.Type)
|
||||
if s.Type == "" {
|
||||
s.Type = corev1.SecretTypeOpaque
|
||||
}
|
||||
s.Data = map[string][]byte{}
|
||||
return s
|
||||
}
|
||||
|
||||
// MakeSecret returns a new secret.
|
||||
func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*corev1.Secret, error) {
|
||||
var all []kv.Pair
|
||||
var err error
|
||||
s := f.makeFreshSecret(args)
|
||||
|
||||
pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"env source file: %s",
|
||||
args.EnvSource))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromLiteralSources(args.LiteralSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"literal sources %v", args.LiteralSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||
"file sources: %v", args.FileSources))
|
||||
}
|
||||
all = append(all, pairs...)
|
||||
|
||||
for _, p := range all {
|
||||
err = addKvToSecret(s, p.Key, p.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if options != nil {
|
||||
s.SetLabels(options.Labels)
|
||||
s.SetAnnotations(options.Annotations)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func addKvToSecret(secret *corev1.Secret, keyName, data string) error {
|
||||
// Note, the rules for SecretKeys keys are the exact same as the ones for ConfigMap.
|
||||
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
|
||||
return fmt.Errorf("%q is not a valid key name for a Secret: %s", keyName, strings.Join(errs, ";"))
|
||||
}
|
||||
if _, entryExists := secret.Data[keyName]; entryExists {
|
||||
return fmt.Errorf("cannot add key %s, another key by that name already exists", keyName)
|
||||
}
|
||||
secret.Data[keyName] = []byte(data)
|
||||
return nil
|
||||
}
|
||||
76
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/doc.go
generated
vendored
76
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/doc.go
generated
vendored
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// It's possible that kustomize's features will be vendored into
|
||||
// the kubernetes/kubernetes repo and made available to kubectl
|
||||
// commands, while at the same time the kustomize program will
|
||||
// continue to exist as an independent CLI. Vendoring snapshots
|
||||
// would be taken just before a kubectl release.
|
||||
//
|
||||
// This creates a problem in that freestanding-kustomize depends on
|
||||
// (for example):
|
||||
//
|
||||
// https://github.com/kubernetes/apimachinery/
|
||||
// tree/master/pkg/util/yaml
|
||||
//
|
||||
// It vendors that package into
|
||||
// sigs.k8s.io/kustomize/vendor/k8s.io/apimachinery/
|
||||
//
|
||||
// Whereas kubectl-kustomize would have to depend on the "staging"
|
||||
// version of this code, located at
|
||||
//
|
||||
// https://github.com/kubernetes/kubernetes/
|
||||
// blob/master/staging/src/k8s.io/apimachinery/pkg/util/yaml
|
||||
//
|
||||
// which is "vendored" via symlinks:
|
||||
// k8s.io/kubernetes/vendor/k8s.io/apimachinery
|
||||
// is a symlink to
|
||||
// ../../staging/src/k8s.io/apimachinery
|
||||
//
|
||||
// The staging version is the canonical, under-development
|
||||
// version of the code that kubectl depends on, whereas the packages
|
||||
// at kubernetes/apimachinery are periodic snapshots of staging made
|
||||
// for outside tools to depend on.
|
||||
//
|
||||
// apimachinery isn't the only package that poses this problem, just
|
||||
// using it as a specific example.
|
||||
//
|
||||
// The kubectl binary cannot vendor in kustomize code that in
|
||||
// turn vendors in the non-staging packages.
|
||||
//
|
||||
// One way to fix some of this would be to copy code - a hard fork.
|
||||
// This has all the problems associated with a hard forking.
|
||||
//
|
||||
// Another way would be to break the kustomize repo into three:
|
||||
//
|
||||
// (1) kustomize - repo with the main() function,
|
||||
// vendoring (2) and (3).
|
||||
//
|
||||
// (2) kustomize-libs - packages used by (1) with no
|
||||
// apimachinery dependence.
|
||||
//
|
||||
// (3) kustomize-k8sdeps - A thin code layer that depends
|
||||
// on (vendors) apimachinery to provide thin implementations
|
||||
// to interfaces used in (2).
|
||||
//
|
||||
// The kubectl repo would then vendor from (2) only, and have
|
||||
// a local implementation of (3). With that in mind, it's clear
|
||||
// that (3) doesn't have to be a repo; the kustomize version of
|
||||
// the thin layer can live directly in (1).
|
||||
//
|
||||
// This package is the code in (3), meant for kustomize.
|
||||
|
||||
package k8sdeps
|
||||
34
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/factory.go
generated
vendored
34
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/factory.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
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 k8sdeps provides kustomize factory with k8s dependencies
|
||||
package k8sdeps
|
||||
|
||||
import (
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct"
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer"
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator"
|
||||
"sigs.k8s.io/kustomize/pkg/factory"
|
||||
)
|
||||
|
||||
// NewFactory creates an instance of KustFactory using k8sdeps factories
|
||||
func NewFactory() *factory.KustFactory {
|
||||
return factory.NewKustFactory(
|
||||
kunstruct.NewKunstructuredFactoryImpl(),
|
||||
validator.NewKustValidator(),
|
||||
transformer.NewFactoryImpl(),
|
||||
)
|
||||
}
|
||||
118
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct/factory.go
generated
vendored
118
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct/factory.go
generated
vendored
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
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 kunstruct
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// KunstructuredFactoryImpl hides construction using apimachinery types.
|
||||
type KunstructuredFactoryImpl struct {
|
||||
cmFactory *configmapandsecret.ConfigMapFactory
|
||||
secretFactory *configmapandsecret.SecretFactory
|
||||
}
|
||||
|
||||
var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{}
|
||||
|
||||
// NewKunstructuredFactoryImpl returns a factory.
|
||||
func NewKunstructuredFactoryImpl() ifc.KunstructuredFactory {
|
||||
return &KunstructuredFactoryImpl{}
|
||||
}
|
||||
|
||||
// SliceFromBytes returns a slice of Kunstructured.
|
||||
func (kf *KunstructuredFactoryImpl) SliceFromBytes(
|
||||
in []byte) ([]ifc.Kunstructured, error) {
|
||||
decoder := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(in), 1024)
|
||||
var result []ifc.Kunstructured
|
||||
var err error
|
||||
for err == nil || isEmptyYamlError(err) {
|
||||
var out unstructured.Unstructured
|
||||
err = decoder.Decode(&out)
|
||||
if err == nil {
|
||||
if len(out.Object) == 0 {
|
||||
continue
|
||||
}
|
||||
err = kf.validate(out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, &UnstructAdapter{Unstructured: out})
|
||||
}
|
||||
}
|
||||
if err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func isEmptyYamlError(err error) bool {
|
||||
return strings.Contains(err.Error(), "is missing in 'null'")
|
||||
}
|
||||
|
||||
// FromMap returns an instance of Kunstructured.
|
||||
func (kf *KunstructuredFactoryImpl) FromMap(
|
||||
m map[string]interface{}) ifc.Kunstructured {
|
||||
return &UnstructAdapter{Unstructured: unstructured.Unstructured{Object: m}}
|
||||
}
|
||||
|
||||
// MakeConfigMap returns an instance of Kunstructured for ConfigMap
|
||||
func (kf *KunstructuredFactoryImpl) MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) {
|
||||
cm, err := kf.cmFactory.MakeConfigMap(args, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewKunstructuredFromObject(cm)
|
||||
}
|
||||
|
||||
// MakeSecret returns an instance of Kunstructured for Secret
|
||||
func (kf *KunstructuredFactoryImpl) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) {
|
||||
sec, err := kf.secretFactory.MakeSecret(args, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewKunstructuredFromObject(sec)
|
||||
}
|
||||
|
||||
// Set sets loader
|
||||
func (kf *KunstructuredFactoryImpl) Set(ldr ifc.Loader) {
|
||||
kf.cmFactory = configmapandsecret.NewConfigMapFactory(ldr)
|
||||
kf.secretFactory = configmapandsecret.NewSecretFactory(ldr)
|
||||
}
|
||||
|
||||
// validate validates that u has kind and name
|
||||
// except for kind `List`, which doesn't require a name
|
||||
func (kf *KunstructuredFactoryImpl) validate(u unstructured.Unstructured) error {
|
||||
kind := u.GetKind()
|
||||
if kind == "" {
|
||||
return fmt.Errorf("missing kind in object %v", u)
|
||||
} else if strings.HasSuffix(kind, "List") {
|
||||
return nil
|
||||
}
|
||||
if u.GetName() == "" {
|
||||
return fmt.Errorf("missing metadata.name in object %v", u)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
71
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct/helper.go
generated
vendored
71
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct/helper.go
generated
vendored
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
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 kunstruct provides unstructured from api machinery and factory for creating unstructured
|
||||
package kunstruct
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseFields(path string) ([]string, error) {
|
||||
if !strings.Contains(path, "[") {
|
||||
return strings.Split(path, "."), nil
|
||||
}
|
||||
|
||||
var fields []string
|
||||
start := 0
|
||||
insideParentheses := false
|
||||
for i := range path {
|
||||
switch path[i] {
|
||||
case '.':
|
||||
if !insideParentheses {
|
||||
fields = append(fields, path[start:i])
|
||||
start = i + 1
|
||||
}
|
||||
case '[':
|
||||
if !insideParentheses {
|
||||
if i == start {
|
||||
start = i + 1
|
||||
} else {
|
||||
fields = append(fields, path[start:i])
|
||||
start = i + 1
|
||||
}
|
||||
insideParentheses = true
|
||||
} else {
|
||||
return nil, fmt.Errorf("nested parentheses are not allowed: %s", path)
|
||||
}
|
||||
case ']':
|
||||
if insideParentheses {
|
||||
fields = append(fields, path[start:i])
|
||||
start = i + 1
|
||||
insideParentheses = false
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid field path %s", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
if start < len(path)-1 {
|
||||
fields = append(fields, path[start:])
|
||||
}
|
||||
for i, f := range fields {
|
||||
if strings.HasPrefix(f, "\"") || strings.HasPrefix(f, "'") {
|
||||
fields[i] = strings.Trim(f, "\"'")
|
||||
}
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
92
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct/kunstruct.go
generated
vendored
92
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct/kunstruct.go
generated
vendored
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
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 kunstruct provides unstructured from api machinery and factory for creating unstructured
|
||||
package kunstruct
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
var _ ifc.Kunstructured = &UnstructAdapter{}
|
||||
|
||||
// UnstructAdapter wraps unstructured.Unstructured from
|
||||
// https://github.com/kubernetes/apimachinery/blob/master/
|
||||
// pkg/apis/meta/v1/unstructured/unstructured.go
|
||||
// to isolate dependence on apimachinery.
|
||||
type UnstructAdapter struct {
|
||||
unstructured.Unstructured
|
||||
}
|
||||
|
||||
// NewKunstructuredFromObject returns a new instance of Kunstructured.
|
||||
func NewKunstructuredFromObject(obj runtime.Object) (ifc.Kunstructured, error) {
|
||||
// Convert obj to a byte stream, then convert that to JSON (Unstructured).
|
||||
marshaled, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return &UnstructAdapter{}, err
|
||||
}
|
||||
var u unstructured.Unstructured
|
||||
err = u.UnmarshalJSON(marshaled)
|
||||
// creationTimestamp always 'null', remove it
|
||||
u.SetCreationTimestamp(metav1.Time{})
|
||||
return &UnstructAdapter{Unstructured: u}, err
|
||||
}
|
||||
|
||||
// GetGvk returns the Gvk name of the object.
|
||||
func (fs *UnstructAdapter) GetGvk() gvk.Gvk {
|
||||
x := fs.GroupVersionKind()
|
||||
return gvk.Gvk{
|
||||
Group: x.Group,
|
||||
Version: x.Version,
|
||||
Kind: x.Kind,
|
||||
}
|
||||
}
|
||||
|
||||
// Copy provides a copy behind an interface.
|
||||
func (fs *UnstructAdapter) Copy() ifc.Kunstructured {
|
||||
return &UnstructAdapter{*fs.DeepCopy()}
|
||||
}
|
||||
|
||||
// Map returns the unstructured content map.
|
||||
func (fs *UnstructAdapter) Map() map[string]interface{} {
|
||||
return fs.Object
|
||||
}
|
||||
|
||||
// SetMap overrides the unstructured content map.
|
||||
func (fs *UnstructAdapter) SetMap(m map[string]interface{}) {
|
||||
fs.Object = m
|
||||
}
|
||||
|
||||
// GetFieldValue returns value at the given fieldpath.
|
||||
func (fs *UnstructAdapter) GetFieldValue(path string) (string, error) {
|
||||
fields, err := parseFields(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s, found, err := unstructured.NestedString(
|
||||
fs.UnstructuredContent(), fields...)
|
||||
if found || err != nil {
|
||||
return s, err
|
||||
}
|
||||
return "", fmt.Errorf("no field named '%s'", path)
|
||||
}
|
||||
102
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kv/kv.go
generated
vendored
102
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kv/kv.go
generated
vendored
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 kv
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
)
|
||||
|
||||
// Pair represents a <key, value> pair.
|
||||
type Pair struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
var utf8bom = []byte{0xEF, 0xBB, 0xBF}
|
||||
|
||||
// KeyValuesFromLines parses given content in to a list of key-value pairs.
|
||||
func KeyValuesFromLines(content []byte) ([]Pair, error) {
|
||||
var kvs []Pair
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(content))
|
||||
currentLine := 0
|
||||
for scanner.Scan() {
|
||||
// Process the current line, retrieving a key/value pair if
|
||||
// possible.
|
||||
scannedBytes := scanner.Bytes()
|
||||
kv, err := KeyValuesFromLine(scannedBytes, currentLine)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentLine++
|
||||
|
||||
if len(kv.Key) == 0 {
|
||||
// no key means line was empty or a comment
|
||||
continue
|
||||
}
|
||||
|
||||
kvs = append(kvs, kv)
|
||||
}
|
||||
return kvs, nil
|
||||
}
|
||||
|
||||
// KeyValuesFromLine returns a kv with blank key if the line is empty or a comment.
|
||||
// The value will be retrieved from the environment if necessary.
|
||||
func KeyValuesFromLine(line []byte, currentLine int) (Pair, error) {
|
||||
kv := Pair{}
|
||||
|
||||
if !utf8.Valid(line) {
|
||||
return kv, fmt.Errorf("line %d has invalid utf8 bytes : %v", line, string(line))
|
||||
}
|
||||
|
||||
// We trim UTF8 BOM from the first line of the file but no others
|
||||
if currentLine == 0 {
|
||||
line = bytes.TrimPrefix(line, utf8bom)
|
||||
}
|
||||
|
||||
// trim the line from all leading whitespace first
|
||||
line = bytes.TrimLeftFunc(line, unicode.IsSpace)
|
||||
|
||||
// If the line is empty or a comment, we return a blank key/value pair.
|
||||
if len(line) == 0 || line[0] == '#' {
|
||||
return kv, nil
|
||||
}
|
||||
|
||||
data := strings.SplitN(string(line), "=", 2)
|
||||
key := data[0]
|
||||
if errs := validation.IsEnvVarName(key); len(errs) != 0 {
|
||||
return kv, fmt.Errorf("%q is not a valid key name: %s", key, strings.Join(errs, ";"))
|
||||
}
|
||||
|
||||
if len(data) == 2 {
|
||||
kv.Value = data[1]
|
||||
} else {
|
||||
// No value (no `=` in the line) is a signal to obtain the value
|
||||
// from the environment.
|
||||
kv.Value = os.Getenv(key)
|
||||
}
|
||||
kv.Key = key
|
||||
return kv, nil
|
||||
}
|
||||
43
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/factory.go
generated
vendored
43
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/factory.go
generated
vendored
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
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 transformer provides transformer factory
|
||||
package transformer
|
||||
|
||||
import (
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash"
|
||||
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
)
|
||||
|
||||
// FactoryImpl makes patch transformer and name hash transformer
|
||||
type FactoryImpl struct{}
|
||||
|
||||
// NewFactoryImpl makes a new factoryImpl instance
|
||||
func NewFactoryImpl() *FactoryImpl {
|
||||
return &FactoryImpl{}
|
||||
}
|
||||
|
||||
// MakePatchTransformer makes a new patch transformer
|
||||
func (p *FactoryImpl) MakePatchTransformer(slice []*resource.Resource, rf *resource.Factory) (transformers.Transformer, error) {
|
||||
return patch.NewPatchTransformer(slice, rf)
|
||||
}
|
||||
|
||||
// MakeHashTransformer makes a new name hash transformer
|
||||
func (p *FactoryImpl) MakeHashTransformer() transformers.Transformer {
|
||||
return hash.NewNameHashTransformer()
|
||||
}
|
||||
184
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash.go
generated
vendored
184
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash.go
generated
vendored
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
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 hash
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
// KustHash compute hash for unstructured objects
|
||||
type KustHash struct{}
|
||||
|
||||
// NewKustHash returns a KustHash object
|
||||
func NewKustHash() *KustHash {
|
||||
return &KustHash{}
|
||||
}
|
||||
|
||||
// Hash returns a hash of either a ConfigMap or a Secret
|
||||
func (h *KustHash) Hash(m map[string]interface{}) (string, error) {
|
||||
u := unstructured.Unstructured{
|
||||
Object: m,
|
||||
}
|
||||
kind := u.GetKind()
|
||||
switch kind {
|
||||
case "ConfigMap":
|
||||
cm, err := unstructuredToConfigmap(u)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ConfigMapHash(cm)
|
||||
case "Secret":
|
||||
sec, err := unstructuredToSecret(u)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return SecretHash(sec)
|
||||
default:
|
||||
return "", fmt.Errorf("type %s is supported for hashing in %v", kind, m)
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigMapHash returns a hash of the ConfigMap.
|
||||
// The Data, Kind, and Name are taken into account.
|
||||
func ConfigMapHash(cm *v1.ConfigMap) (string, error) {
|
||||
encoded, err := encodeConfigMap(cm)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
h, err := encodeHash(hash(encoded))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// SecretHash returns a hash of the Secret.
|
||||
// The Data, Kind, Name, and Type are taken into account.
|
||||
func SecretHash(sec *v1.Secret) (string, error) {
|
||||
encoded, err := encodeSecret(sec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
h, err := encodeHash(hash(encoded))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// encodeConfigMap encodes a ConfigMap.
|
||||
// Data, Kind, and Name are taken into account.
|
||||
func encodeConfigMap(cm *v1.ConfigMap) (string, error) {
|
||||
// json.Marshal sorts the keys in a stable order in the encoding
|
||||
m := map[string]interface{}{
|
||||
"kind": "ConfigMap",
|
||||
"name": cm.Name,
|
||||
"data": cm.Data,
|
||||
}
|
||||
if cm.Immutable != nil {
|
||||
m["immutable"] = *cm.Immutable
|
||||
}
|
||||
if len(cm.BinaryData) > 0 {
|
||||
m["binaryData"] = cm.BinaryData
|
||||
}
|
||||
data, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
// encodeSecret encodes a Secret.
|
||||
// Data, Kind, Name, and Type are taken into account.
|
||||
func encodeSecret(sec *v1.Secret) (string, error) {
|
||||
// json.Marshal sorts the keys in a stable order in the encoding
|
||||
m := map[string]interface{}{
|
||||
"kind": "Secret",
|
||||
"type": sec.Type,
|
||||
"name": sec.Name,
|
||||
"data": sec.Data,
|
||||
}
|
||||
if sec.Immutable != nil {
|
||||
m["immutable"] = *sec.Immutable
|
||||
}
|
||||
data, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
// encodeHash extracts the first 40 bits of the hash from the hex string
|
||||
// (1 hex char represents 4 bits), and then maps vowels and vowel-like hex
|
||||
// characters to consonants to prevent bad words from being formed (the theory
|
||||
// is that no vowels makes it really hard to make bad words). Since the string
|
||||
// is hex, the only vowels it can contain are 'a' and 'e'.
|
||||
// We picked some arbitrary consonants to map to from the same character set as GenerateName.
|
||||
// See: https://github.com/kubernetes/apimachinery/blob/dc1f89aff9a7509782bde3b68824c8043a3e58cc/pkg/util/rand/rand.go#L75
|
||||
// If the hex string contains fewer than ten characters, returns an error.
|
||||
func encodeHash(hex string) (string, error) {
|
||||
if len(hex) < 10 {
|
||||
return "", fmt.Errorf("the hex string must contain at least 10 characters")
|
||||
}
|
||||
enc := []rune(hex[:10])
|
||||
for i := range enc {
|
||||
switch enc[i] {
|
||||
case '0':
|
||||
enc[i] = 'g'
|
||||
case '1':
|
||||
enc[i] = 'h'
|
||||
case '3':
|
||||
enc[i] = 'k'
|
||||
case 'a':
|
||||
enc[i] = 'm'
|
||||
case 'e':
|
||||
enc[i] = 't'
|
||||
}
|
||||
}
|
||||
return string(enc), nil
|
||||
}
|
||||
|
||||
// hash hashes `data` with sha256 and returns the hex string
|
||||
func hash(data string) string {
|
||||
return fmt.Sprintf("%x", sha256.Sum256([]byte(data)))
|
||||
}
|
||||
|
||||
func unstructuredToConfigmap(u unstructured.Unstructured) (*v1.ConfigMap, error) {
|
||||
marshaled, err := json.Marshal(u.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out v1.ConfigMap
|
||||
err = json.Unmarshal(marshaled, &out)
|
||||
return &out, err
|
||||
}
|
||||
|
||||
func unstructuredToSecret(u unstructured.Unstructured) (*v1.Secret, error) {
|
||||
marshaled, err := json.Marshal(u.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out v1.Secret
|
||||
err = json.Unmarshal(marshaled, &out)
|
||||
return &out, err
|
||||
}
|
||||
47
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/namehash.go
generated
vendored
47
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/namehash.go
generated
vendored
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
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 hash
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
)
|
||||
|
||||
type nameHashTransformer struct{}
|
||||
|
||||
var _ transformers.Transformer = &nameHashTransformer{}
|
||||
|
||||
// NewNameHashTransformer construct a nameHashTransformer.
|
||||
func NewNameHashTransformer() transformers.Transformer {
|
||||
return &nameHashTransformer{}
|
||||
}
|
||||
|
||||
// Transform appends hash to generated resources.
|
||||
func (o *nameHashTransformer) Transform(m resmap.ResMap) error {
|
||||
for _, res := range m {
|
||||
if res.NeedHashSuffix() {
|
||||
h, err := NewKustHash().Hash(res.Map())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res.SetName(fmt.Sprintf("%s-%s", res.GetName(), h))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
174
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch/patch.go
generated
vendored
174
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch/patch.go
generated
vendored
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
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 patch
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
)
|
||||
|
||||
// patchTransformer applies patches.
|
||||
type patchTransformer struct {
|
||||
patches []*resource.Resource
|
||||
rf *resource.Factory
|
||||
}
|
||||
|
||||
var _ transformers.Transformer = &patchTransformer{}
|
||||
|
||||
// NewPatchTransformer constructs a patchTransformer.
|
||||
func NewPatchTransformer(
|
||||
slice []*resource.Resource, rf *resource.Factory) (transformers.Transformer, error) {
|
||||
if len(slice) == 0 {
|
||||
return transformers.NewNoOpTransformer(), nil
|
||||
}
|
||||
return &patchTransformer{patches: slice, rf: rf}, nil
|
||||
}
|
||||
|
||||
// Transform apply the patches on top of the base resources.
|
||||
func (pt *patchTransformer) Transform(baseResourceMap resmap.ResMap) error {
|
||||
// Merge and then index the patches by Id.
|
||||
patches, err := pt.mergePatches()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Strategic merge the resources exist in both base and patches.
|
||||
for _, patch := range patches {
|
||||
// Merge patches with base resource.
|
||||
id := patch.Id()
|
||||
matchedIds := baseResourceMap.GetMatchingIds(id.GvknEquals)
|
||||
if len(matchedIds) == 0 {
|
||||
return fmt.Errorf("failed to find an object with %s to apply the patch", id.GvknString())
|
||||
}
|
||||
if len(matchedIds) > 1 {
|
||||
return fmt.Errorf("found multiple objects %#v targeted by patch %#v (ambiguous)", matchedIds, id)
|
||||
}
|
||||
id = matchedIds[0]
|
||||
base := baseResourceMap[id]
|
||||
merged := map[string]interface{}{}
|
||||
versionedObj, err := scheme.Scheme.New(toSchemaGvk(id.Gvk()))
|
||||
baseName := base.GetName()
|
||||
switch {
|
||||
case runtime.IsNotRegisteredError(err):
|
||||
// Use JSON merge patch to handle types w/o schema
|
||||
baseBytes, err := json.Marshal(base.Map())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
patchBytes, err := json.Marshal(patch.Map())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mergedBytes, err := jsonpatch.MergePatch(baseBytes, patchBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(mergedBytes, &merged)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case err != nil:
|
||||
return err
|
||||
default:
|
||||
// Use Strategic-Merge-Patch to handle types w/ schema
|
||||
// TODO: Change this to use the new Merge package.
|
||||
// Store the name of the base object, because this name may have been munged.
|
||||
// Apply this name to the patched object.
|
||||
lookupPatchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
merged, err = strategicpatch.StrategicMergeMapPatchUsingLookupPatchMeta(
|
||||
base.Map(),
|
||||
patch.Map(),
|
||||
lookupPatchMeta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
base.SetName(baseName)
|
||||
baseResourceMap[id].SetMap(merged)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// mergePatches merge and index patches by Id.
|
||||
// It errors out if there is conflict between patches.
|
||||
func (pt *patchTransformer) mergePatches() (resmap.ResMap, error) {
|
||||
rc := resmap.ResMap{}
|
||||
for ix, patch := range pt.patches {
|
||||
id := patch.Id()
|
||||
existing, found := rc[id]
|
||||
if !found {
|
||||
rc[id] = patch
|
||||
continue
|
||||
}
|
||||
|
||||
versionedObj, err := scheme.Scheme.New(toSchemaGvk(id.Gvk()))
|
||||
if err != nil && !runtime.IsNotRegisteredError(err) {
|
||||
return nil, err
|
||||
}
|
||||
var cd conflictDetector
|
||||
if err != nil {
|
||||
cd = newJMPConflictDetector(pt.rf)
|
||||
} else {
|
||||
cd, err = newSMPConflictDetector(versionedObj, pt.rf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
conflict, err := cd.hasConflict(existing, patch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if conflict {
|
||||
conflictingPatch, err := cd.findConflict(ix, pt.patches)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf(
|
||||
"conflict between %#v and %#v",
|
||||
conflictingPatch.Map(), patch.Map())
|
||||
}
|
||||
merged, err := cd.mergePatches(existing, patch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc[id] = merged
|
||||
}
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
// toSchemaGvk converts to a schema.GroupVersionKind.
|
||||
func toSchemaGvk(x gvk.Gvk) schema.GroupVersionKind {
|
||||
return schema.GroupVersionKind{
|
||||
Group: x.Group,
|
||||
Version: x.Version,
|
||||
Kind: x.Kind,
|
||||
}
|
||||
}
|
||||
137
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch/patchconflictdetector.go
generated
vendored
137
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch/patchconflictdetector.go
generated
vendored
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
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 patch
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
)
|
||||
|
||||
type conflictDetector interface {
|
||||
hasConflict(patch1, patch2 *resource.Resource) (bool, error)
|
||||
findConflict(conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error)
|
||||
mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error)
|
||||
}
|
||||
|
||||
type jsonMergePatch struct {
|
||||
rf *resource.Factory
|
||||
}
|
||||
|
||||
var _ conflictDetector = &jsonMergePatch{}
|
||||
|
||||
func newJMPConflictDetector(rf *resource.Factory) conflictDetector {
|
||||
return &jsonMergePatch{rf: rf}
|
||||
}
|
||||
|
||||
func (jmp *jsonMergePatch) hasConflict(
|
||||
patch1, patch2 *resource.Resource) (bool, error) {
|
||||
return mergepatch.HasConflicts(patch1.Map(), patch2.Map())
|
||||
}
|
||||
|
||||
func (jmp *jsonMergePatch) findConflict(
|
||||
conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error) {
|
||||
for i, patch := range patches {
|
||||
if i == conflictingPatchIdx {
|
||||
continue
|
||||
}
|
||||
if !patches[conflictingPatchIdx].Id().GvknEquals(patch.Id()) {
|
||||
continue
|
||||
}
|
||||
conflict, err := mergepatch.HasConflicts(
|
||||
patch.Map(),
|
||||
patches[conflictingPatchIdx].Map())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if conflict {
|
||||
return patch, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (jmp *jsonMergePatch) mergePatches(
|
||||
patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
||||
baseBytes, err := json.Marshal(patch1.Map())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patchBytes, err := json.Marshal(patch2.Map())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mergedBytes, err := jsonpatch.MergeMergePatches(baseBytes, patchBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mergedMap := make(map[string]interface{})
|
||||
err = json.Unmarshal(mergedBytes, &mergedMap)
|
||||
return jmp.rf.FromMap(mergedMap), err
|
||||
}
|
||||
|
||||
type strategicMergePatch struct {
|
||||
lookupPatchMeta strategicpatch.LookupPatchMeta
|
||||
rf *resource.Factory
|
||||
}
|
||||
|
||||
var _ conflictDetector = &strategicMergePatch{}
|
||||
|
||||
func newSMPConflictDetector(
|
||||
versionedObj runtime.Object,
|
||||
rf *resource.Factory) (conflictDetector, error) {
|
||||
lookupPatchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObj)
|
||||
return &strategicMergePatch{lookupPatchMeta: lookupPatchMeta, rf: rf}, err
|
||||
}
|
||||
|
||||
func (smp *strategicMergePatch) hasConflict(p1, p2 *resource.Resource) (bool, error) {
|
||||
return strategicpatch.MergingMapsHaveConflicts(
|
||||
p1.Map(), p2.Map(), smp.lookupPatchMeta)
|
||||
}
|
||||
|
||||
func (smp *strategicMergePatch) findConflict(
|
||||
conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error) {
|
||||
for i, patch := range patches {
|
||||
if i == conflictingPatchIdx {
|
||||
continue
|
||||
}
|
||||
if !patches[conflictingPatchIdx].Id().GvknEquals(patch.Id()) {
|
||||
continue
|
||||
}
|
||||
conflict, err := strategicpatch.MergingMapsHaveConflicts(
|
||||
patch.Map(),
|
||||
patches[conflictingPatchIdx].Map(),
|
||||
smp.lookupPatchMeta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if conflict {
|
||||
return patch, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (smp *strategicMergePatch) mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
||||
mergeJSONMap, err := strategicpatch.MergeStrategicMergeMapPatchUsingLookupPatchMeta(
|
||||
smp.lookupPatchMeta, patch1.Map(), patch2.Map())
|
||||
return smp.rf.FromMap(mergeJSONMap), err
|
||||
}
|
||||
61
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator/validators.go
generated
vendored
61
vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator/validators.go
generated
vendored
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
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 validator provides functions to validate labels, annotations, namespace using apimachinery
|
||||
package validator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
apivalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||
v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// KustValidator validates Labels and annotations by apimachinery
|
||||
type KustValidator struct{}
|
||||
|
||||
// NewKustValidator returns a KustValidator object
|
||||
func NewKustValidator() *KustValidator {
|
||||
return &KustValidator{}
|
||||
}
|
||||
|
||||
// MakeAnnotationValidator returns a MapValidatorFunc using apimachinery.
|
||||
func (v *KustValidator) MakeAnnotationValidator() func(map[string]string) error {
|
||||
return func(x map[string]string) error {
|
||||
errs := apivalidation.ValidateAnnotations(x, field.NewPath("field"))
|
||||
if len(errs) > 0 {
|
||||
return errors.New(errs.ToAggregate().Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// MakeLabelValidator returns a MapValidatorFunc using apimachinery.
|
||||
func (v *KustValidator) MakeLabelValidator() func(map[string]string) error {
|
||||
return func(x map[string]string) error {
|
||||
errs := v1validation.ValidateLabels(x, field.NewPath("field"))
|
||||
if len(errs) > 0 {
|
||||
return errors.New(errs.ToAggregate().Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateNamespace validates a string is a valid namespace using apimachinery.
|
||||
func (v *KustValidator) ValidateNamespace(s string) []string {
|
||||
return validation.IsDNS1123Label(s)
|
||||
}
|
||||
59
vendor/k8s.io/cli-runtime/pkg/printers/managedfields.go
generated
vendored
Normal file
59
vendor/k8s.io/cli-runtime/pkg/printers/managedfields.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2021 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 printers
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// OmitManagedFieldsPrinter wraps an existing printer and omits the managed fields from the object
|
||||
// before printing it.
|
||||
type OmitManagedFieldsPrinter struct {
|
||||
Delegate ResourcePrinter
|
||||
}
|
||||
|
||||
var _ ResourcePrinter = (*OmitManagedFieldsPrinter)(nil)
|
||||
|
||||
func omitManagedFields(o runtime.Object) runtime.Object {
|
||||
a, err := meta.Accessor(o)
|
||||
if err != nil {
|
||||
// The object is not a `metav1.Object`, ignore it.
|
||||
return o
|
||||
}
|
||||
a.SetManagedFields(nil)
|
||||
return o
|
||||
}
|
||||
|
||||
// PrintObj copies the object and omits the managed fields from the copied object before printing it.
|
||||
func (p *OmitManagedFieldsPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
if obj == nil {
|
||||
return p.Delegate.PrintObj(obj, w)
|
||||
}
|
||||
if meta.IsListType(obj) {
|
||||
obj = obj.DeepCopyObject()
|
||||
_ = meta.EachListItem(obj, func(item runtime.Object) error {
|
||||
omitManagedFields(item)
|
||||
return nil
|
||||
})
|
||||
} else if _, err := meta.Accessor(obj); err == nil {
|
||||
obj = omitManagedFields(obj.DeepCopyObject())
|
||||
}
|
||||
return p.Delegate.PrintObj(obj, w)
|
||||
}
|
||||
5
vendor/k8s.io/cli-runtime/pkg/printers/tableprinter.go
generated
vendored
5
vendor/k8s.io/cli-runtime/pkg/printers/tableprinter.go
generated
vendored
@@ -94,9 +94,8 @@ func printHeader(columnNames []string, w io.Writer) error {
|
||||
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
|
||||
func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error {
|
||||
|
||||
w, found := output.(*tabwriter.Writer)
|
||||
if !found {
|
||||
w = GetNewTabWriter(output)
|
||||
if _, found := output.(*tabwriter.Writer); !found {
|
||||
w := GetNewTabWriter(output)
|
||||
output = w
|
||||
defer w.Flush()
|
||||
}
|
||||
|
||||
46
vendor/k8s.io/cli-runtime/pkg/resource/builder.go
generated
vendored
46
vendor/k8s.io/cli-runtime/pkg/resource/builder.go
generated
vendored
@@ -35,7 +35,10 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/restmapper"
|
||||
"sigs.k8s.io/kustomize/api/filesys"
|
||||
)
|
||||
|
||||
var FileExtensions = []string{".json", ".yaml", ".yml"}
|
||||
@@ -100,8 +103,6 @@ type Builder struct {
|
||||
|
||||
singleItemImplied bool
|
||||
|
||||
export bool
|
||||
|
||||
schema ContentValidator
|
||||
|
||||
// fakeClientFn is used for testing
|
||||
@@ -178,6 +179,25 @@ func newBuilder(clientConfigFn ClientConfigFunc, restMapper RESTMapperFunc, cate
|
||||
}
|
||||
}
|
||||
|
||||
// noopClientGetter implements RESTClientGetter returning only errors.
|
||||
// used as a dummy getter in a local-only builder.
|
||||
type noopClientGetter struct{}
|
||||
|
||||
func (noopClientGetter) ToRESTConfig() (*rest.Config, error) {
|
||||
return nil, fmt.Errorf("local operation only")
|
||||
}
|
||||
func (noopClientGetter) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
|
||||
return nil, fmt.Errorf("local operation only")
|
||||
}
|
||||
func (noopClientGetter) ToRESTMapper() (meta.RESTMapper, error) {
|
||||
return nil, fmt.Errorf("local operation only")
|
||||
}
|
||||
|
||||
// NewLocalBuilder returns a builder that is configured not to create REST clients and avoids asking the server for results.
|
||||
func NewLocalBuilder() *Builder {
|
||||
return NewBuilder(noopClientGetter{}).Local()
|
||||
}
|
||||
|
||||
func NewBuilder(restClientGetter RESTClientGetter) *Builder {
|
||||
categoryExpanderFn := func() (restmapper.CategoryExpander, error) {
|
||||
discoveryClient, err := restClientGetter.ToDiscoveryClient()
|
||||
@@ -239,8 +259,14 @@ func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *Filename
|
||||
}
|
||||
}
|
||||
if filenameOptions.Kustomize != "" {
|
||||
b.paths = append(b.paths, &KustomizeVisitor{filenameOptions.Kustomize,
|
||||
NewStreamVisitor(nil, b.mapper, filenameOptions.Kustomize, b.schema)})
|
||||
b.paths = append(
|
||||
b.paths,
|
||||
&KustomizeVisitor{
|
||||
mapper: b.mapper,
|
||||
dirPath: filenameOptions.Kustomize,
|
||||
schema: b.schema,
|
||||
fSys: filesys.MakeFsOnDisk(),
|
||||
})
|
||||
}
|
||||
|
||||
if enforceNamespace {
|
||||
@@ -461,12 +487,6 @@ func (b *Builder) FieldSelectorParam(s string) *Builder {
|
||||
return b
|
||||
}
|
||||
|
||||
// ExportParam accepts the export boolean for these resources
|
||||
func (b *Builder) ExportParam(export bool) *Builder {
|
||||
b.export = export
|
||||
return b
|
||||
}
|
||||
|
||||
// NamespaceParam accepts the namespace that these resources should be
|
||||
// considered under from - used by DefaultNamespace() and RequireNamespace()
|
||||
func (b *Builder) NamespaceParam(namespace string) *Builder {
|
||||
@@ -826,7 +846,7 @@ func (b *Builder) visitorResult() *Result {
|
||||
return &Result{err: err}
|
||||
}
|
||||
}
|
||||
return &Result{err: fmt.Errorf("resource(s) were provided, but no name, label selector, or --all flag specified")}
|
||||
return &Result{err: fmt.Errorf("resource(s) were provided, but no name was specified")}
|
||||
}
|
||||
return &Result{err: missingResourceError}
|
||||
}
|
||||
@@ -870,7 +890,7 @@ func (b *Builder) visitBySelector() *Result {
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
}
|
||||
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, labelSelector, fieldSelector, b.export, b.limitChunks))
|
||||
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, labelSelector, fieldSelector, b.limitChunks))
|
||||
}
|
||||
if b.continueOnError {
|
||||
result.visitor = EagerVisitorList(visitors)
|
||||
@@ -970,7 +990,6 @@ func (b *Builder) visitByResource() *Result {
|
||||
Mapping: mapping,
|
||||
Namespace: selectorNamespace,
|
||||
Name: tuple.Name,
|
||||
Export: b.export,
|
||||
}
|
||||
items = append(items, info)
|
||||
}
|
||||
@@ -1035,7 +1054,6 @@ func (b *Builder) visitByName() *Result {
|
||||
Mapping: mapping,
|
||||
Namespace: selectorNamespace,
|
||||
Name: name,
|
||||
Export: b.export,
|
||||
}
|
||||
visitors = append(visitors, info)
|
||||
}
|
||||
|
||||
13
vendor/k8s.io/cli-runtime/pkg/resource/dry_run_verifier.go
generated
vendored
13
vendor/k8s.io/cli-runtime/pkg/resource/dry_run_verifier.go
generated
vendored
@@ -20,24 +20,17 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
)
|
||||
|
||||
// VerifyDryRun returns nil if a resource group-version-kind supports
|
||||
// server-side dry-run. Otherwise, an error is returned.
|
||||
func VerifyDryRun(gvk schema.GroupVersionKind, dynamicClient dynamic.Interface, discoveryClient discovery.DiscoveryInterface) error {
|
||||
verifier := NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
return verifier.HasSupport(gvk)
|
||||
}
|
||||
|
||||
func NewDryRunVerifier(dynamicClient dynamic.Interface, discoveryClient discovery.DiscoveryInterface) *DryRunVerifier {
|
||||
func NewDryRunVerifier(dynamicClient dynamic.Interface, openAPIGetter discovery.OpenAPISchemaInterface) *DryRunVerifier {
|
||||
return &DryRunVerifier{
|
||||
finder: NewCRDFinder(CRDFromDynamic(dynamicClient)),
|
||||
openAPIGetter: discoveryClient,
|
||||
openAPIGetter: openAPIGetter,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
33
vendor/k8s.io/cli-runtime/pkg/resource/helper.go
generated
vendored
33
vendor/k8s.io/cli-runtime/pkg/resource/helper.go
generated
vendored
@@ -18,7 +18,6 @@ package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -46,6 +45,10 @@ type Helper struct {
|
||||
// and on resources that support dry-run. If the apiserver or the resource
|
||||
// does not support dry-run, then the change will be persisted to storage.
|
||||
ServerDryRun bool
|
||||
|
||||
// FieldManager is the name associated with the actor or entity that is making
|
||||
// changes.
|
||||
FieldManager string
|
||||
}
|
||||
|
||||
// NewHelper creates a Helper from a ResourceMapping
|
||||
@@ -64,27 +67,26 @@ func (m *Helper) DryRun(dryRun bool) *Helper {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Helper) Get(namespace, name string, export bool) (runtime.Object, error) {
|
||||
// WithFieldManager sets the field manager option to indicate the actor or entity
|
||||
// that is making changes in a create or update operation.
|
||||
func (m *Helper) WithFieldManager(fieldManager string) *Helper {
|
||||
m.FieldManager = fieldManager
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Helper) Get(namespace, name string) (runtime.Object, error) {
|
||||
req := m.RESTClient.Get().
|
||||
NamespaceIfScoped(namespace, m.NamespaceScoped).
|
||||
Resource(m.Resource).
|
||||
Name(name)
|
||||
if export {
|
||||
// TODO: I should be part of GetOptions
|
||||
req.Param("export", strconv.FormatBool(export))
|
||||
}
|
||||
return req.Do(context.TODO()).Get()
|
||||
}
|
||||
|
||||
func (m *Helper) List(namespace, apiVersion string, export bool, options *metav1.ListOptions) (runtime.Object, error) {
|
||||
func (m *Helper) List(namespace, apiVersion string, options *metav1.ListOptions) (runtime.Object, error) {
|
||||
req := m.RESTClient.Get().
|
||||
NamespaceIfScoped(namespace, m.NamespaceScoped).
|
||||
Resource(m.Resource).
|
||||
VersionedParams(options, metav1.ParameterCodec)
|
||||
if export {
|
||||
// TODO: I should be part of ListOptions
|
||||
req.Param("export", strconv.FormatBool(export))
|
||||
}
|
||||
return req.Do(context.TODO()).Get()
|
||||
}
|
||||
|
||||
@@ -141,6 +143,9 @@ func (m *Helper) CreateWithOptions(namespace string, modify bool, obj runtime.Ob
|
||||
if m.ServerDryRun {
|
||||
options.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
if m.FieldManager != "" {
|
||||
options.FieldManager = m.FieldManager
|
||||
}
|
||||
if modify {
|
||||
// Attempt to version the object based on client logic.
|
||||
version, err := metadataAccessor.ResourceVersion(obj)
|
||||
@@ -174,6 +179,9 @@ func (m *Helper) Patch(namespace, name string, pt types.PatchType, data []byte,
|
||||
if m.ServerDryRun {
|
||||
options.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
if m.FieldManager != "" {
|
||||
options.FieldManager = m.FieldManager
|
||||
}
|
||||
return m.RESTClient.Patch(pt).
|
||||
NamespaceIfScoped(namespace, m.NamespaceScoped).
|
||||
Resource(m.Resource).
|
||||
@@ -190,6 +198,9 @@ func (m *Helper) Replace(namespace, name string, overwrite bool, obj runtime.Obj
|
||||
if m.ServerDryRun {
|
||||
options.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
if m.FieldManager != "" {
|
||||
options.FieldManager = m.FieldManager
|
||||
}
|
||||
|
||||
// Attempt to version the object based on client logic.
|
||||
version, err := metadataAccessor.ResourceVersion(obj)
|
||||
|
||||
54
vendor/k8s.io/cli-runtime/pkg/resource/kustomizevisitor.go
generated
vendored
Normal file
54
vendor/k8s.io/cli-runtime/pkg/resource/kustomizevisitor.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2019 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 resource
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/filesys"
|
||||
"sigs.k8s.io/kustomize/api/krusty"
|
||||
)
|
||||
|
||||
// KustomizeVisitor handles kustomization.yaml files.
|
||||
type KustomizeVisitor struct {
|
||||
mapper *mapper
|
||||
schema ContentValidator
|
||||
// Directory expected to contain a kustomization file.
|
||||
dirPath string
|
||||
// File system containing dirPath.
|
||||
fSys filesys.FileSystem
|
||||
// Holds result of kustomize build, retained for tests.
|
||||
yml []byte
|
||||
}
|
||||
|
||||
// Visit passes the result of a kustomize build to a StreamVisitor.
|
||||
func (v *KustomizeVisitor) Visit(fn VisitorFunc) error {
|
||||
kOpts := krusty.MakeDefaultOptions()
|
||||
kOpts.DoLegacyResourceSort = true
|
||||
k := krusty.MakeKustomizer(kOpts)
|
||||
m, err := k.Run(v.fSys, v.dirPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.yml, err = m.AsYaml()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sv := NewStreamVisitor(
|
||||
bytes.NewReader(v.yml), v.mapper, v.dirPath, v.schema)
|
||||
return sv.Visit(fn)
|
||||
}
|
||||
2
vendor/k8s.io/cli-runtime/pkg/resource/metadata_decoder.go
generated
vendored
2
vendor/k8s.io/cli-runtime/pkg/resource/metadata_decoder.go
generated
vendored
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// hold a single instance of the case-sensitive decoder
|
||||
var caseSensitiveJsonIterator = json.CaseSensitiveJsonIterator()
|
||||
var caseSensitiveJsonIterator = json.CaseSensitiveJSONIterator()
|
||||
|
||||
// metadataValidatingDecoder wraps a decoder and additionally ensures metadata schema fields decode before returning an unstructured object
|
||||
type metadataValidatingDecoder struct {
|
||||
|
||||
5
vendor/k8s.io/cli-runtime/pkg/resource/selector.go
generated
vendored
5
vendor/k8s.io/cli-runtime/pkg/resource/selector.go
generated
vendored
@@ -32,19 +32,17 @@ type Selector struct {
|
||||
Namespace string
|
||||
LabelSelector string
|
||||
FieldSelector string
|
||||
Export bool
|
||||
LimitChunks int64
|
||||
}
|
||||
|
||||
// NewSelector creates a resource selector which hides details of getting items by their label selector.
|
||||
func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace, labelSelector, fieldSelector string, export bool, limitChunks int64) *Selector {
|
||||
func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace, labelSelector, fieldSelector string, limitChunks int64) *Selector {
|
||||
return &Selector{
|
||||
Client: client,
|
||||
Mapping: mapping,
|
||||
Namespace: namespace,
|
||||
LabelSelector: labelSelector,
|
||||
FieldSelector: fieldSelector,
|
||||
Export: export,
|
||||
LimitChunks: limitChunks,
|
||||
}
|
||||
}
|
||||
@@ -56,7 +54,6 @@ func (r *Selector) Visit(fn VisitorFunc) error {
|
||||
list, err := NewHelper(r.Client, r.Mapping).List(
|
||||
r.Namespace,
|
||||
r.ResourceMapping().GroupVersionKind.GroupVersion().String(),
|
||||
r.Export,
|
||||
&metav1.ListOptions{
|
||||
LabelSelector: r.LabelSelector,
|
||||
FieldSelector: r.FieldSelector,
|
||||
|
||||
26
vendor/k8s.io/cli-runtime/pkg/resource/visitor.go
generated
vendored
26
vendor/k8s.io/cli-runtime/pkg/resource/visitor.go
generated
vendored
@@ -30,9 +30,6 @@ import (
|
||||
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
"golang.org/x/text/transform"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -42,7 +39,6 @@ import (
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/cli-runtime/pkg/kustomize"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -88,8 +84,6 @@ type Info struct {
|
||||
// but if set it should be equal to or newer than the resource version of the
|
||||
// object (however the server defines resource version).
|
||||
ResourceVersion string
|
||||
// Optional, should this resource be exported, stripped of cluster-specific and instance specific fields
|
||||
Export bool
|
||||
}
|
||||
|
||||
// Visit implements Visitor
|
||||
@@ -99,7 +93,7 @@ func (i *Info) Visit(fn VisitorFunc) error {
|
||||
|
||||
// Get retrieves the object from the Namespace and Name fields
|
||||
func (i *Info) Get() (err error) {
|
||||
obj, err := NewHelper(i.Client, i.Mapping).Get(i.Namespace, i.Name, i.Export)
|
||||
obj, err := NewHelper(i.Client, i.Mapping).Get(i.Namespace, i.Name)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) && len(i.Namespace) > 0 && i.Namespace != metav1.NamespaceDefault && i.Namespace != metav1.NamespaceAll {
|
||||
err2 := i.Client.Get().AbsPath("api", "v1", "namespaces", i.Namespace).Do(context.TODO()).Error()
|
||||
@@ -530,24 +524,6 @@ func (v *FileVisitor) Visit(fn VisitorFunc) error {
|
||||
return v.StreamVisitor.Visit(fn)
|
||||
}
|
||||
|
||||
// KustomizeVisitor is wrapper around a StreamVisitor, to handle Kustomization directories
|
||||
type KustomizeVisitor struct {
|
||||
Path string
|
||||
*StreamVisitor
|
||||
}
|
||||
|
||||
// Visit in a KustomizeVisitor gets the output of Kustomize build and save it in the Streamvisitor
|
||||
func (v *KustomizeVisitor) Visit(fn VisitorFunc) error {
|
||||
fSys := fs.MakeRealFS()
|
||||
var out bytes.Buffer
|
||||
err := kustomize.RunKustomizeBuild(&out, fSys, v.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.StreamVisitor.Reader = bytes.NewReader(out.Bytes())
|
||||
return v.StreamVisitor.Visit(fn)
|
||||
}
|
||||
|
||||
// StreamVisitor reads objects from an io.Reader and walks them. A stream visitor can only be
|
||||
// visited once.
|
||||
// TODO: depends on objects being in JSON format before being passed to decode - need to implement
|
||||
|
||||
Reference in New Issue
Block a user