Skip to content

Commit

Permalink
Remove dependency on cli-runtime (#413)
Browse files Browse the repository at this point in the history
* first pass: kubectl flags must be passed after '--'

* add warning when using non-separated flags

* mark flags as deprecated

* drop defaultCacheDir and homedir dependency
  • Loading branch information
imjasonh authored Aug 10, 2021
1 parent 9f6e0d3 commit 466dbab
Show file tree
Hide file tree
Showing 1,235 changed files with 235 additions and 507,904 deletions.
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.6
github.com/google/go-containerregistry v0.6.0
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
github.com/klauspost/compress v1.13.1 // indirect
github.com/mattmoor/dep-notify v0.0.0-20190205035814-a45dec370a17
github.com/mattn/go-isatty v0.0.13 // indirect
Expand All @@ -22,10 +21,10 @@ require (
github.com/spf13/viper v1.8.1
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/tools v0.1.5
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
k8s.io/apimachinery v0.21.3
k8s.io/cli-runtime v0.20.6
k8s.io/apimachinery v0.22.0
sigs.k8s.io/kind v0.11.1
)
66 changes: 21 additions & 45 deletions go.sum

Large diffs are not rendered by default.

125 changes: 125 additions & 0 deletions internal/k8sflags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright 2021 Google LLC All Rights Reserved.
//
// 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 internal

import (
"strings"

"github.com/spf13/pflag"
)

// AddFlags adds kubectl global flags to the given flagset.
func AddFlags(f *KubectlFlags, flags *pflag.FlagSet) {
flags.StringVar(&f.kubeConfig, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests. (DEPRECATED)")
flags.StringVar(&f.cacheDir, "cache-dir", "", "Default cache directory (DEPRECATED)")
flags.StringVar(&f.certFile, "client-certificate", "", "Path to a client certificate file for TLS (DEPRECATED)")
flags.StringVar(&f.keyFile, "client-key", "", "Path to a client key file for TLS (DEPRECATED)")
flags.StringVar(&f.bearerToken, "token", "", "Bearer token for authentication to the API server (DEPRECATED)")
flags.StringVar(&f.impersonate, "as", "", "Username to impersonate for the operation (DEPRECATED)")
flags.StringArrayVar(&f.impersonateGroup, "as-group", []string{}, "Group to impersonate for the operation, this flag can be repeated to specify multiple groups. (DEPRECATED)")
flags.StringVar(&f.username, "username", "", "Username for basic authentication to the API server (DEPRECATED)")
flags.StringVar(&f.password, "password", "", "Password for basic authentication to the API server (DEPRECATED)")
flags.StringVar(&f.clusterName, "cluster", "", "The name of the kubeconfig cluster to use (DEPRECATED)")
flags.StringVar(&f.authInfoName, "user", "", "The name of the kubeconfig user to use (DEPRECATED)")
flags.StringVarP(&f.namespace, "namespace", "n", "", "If present, the namespace scope for this CLI request (DEPRECATED)")
flags.StringVar(&f.context, "context", "", "The name of the kubeconfig context to use (DEPRECATED)")
flags.StringVarP(&f.apiServer, "server", "s", "", "The address and port of the Kubernetes API server (DEPRECATED)")
flags.StringVar(&f.tlsServerName, "tls-server-name", "", "Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used (DEPRECATED)")
flags.BoolVar(&f.insecure, "insecure-skip-tls-verify", false, "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure (DEPRECATED)")
flags.StringVar(&f.caFile, "certificate-authority", "", "Path to a cert file for the certificate authority (DEPRECATED)")
flags.StringVar(&f.timeout, "request-timeout", "", "The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (DEPRECATED)")
}

// KubectlFlags holds kubectl global flag values as parsed from flags.
type KubectlFlags struct {
kubeConfig string
cacheDir string
certFile string
keyFile string
bearerToken string
impersonate string
impersonateGroup []string
username string
password string
clusterName string
authInfoName string
context string
namespace string
apiServer string
tlsServerName string
insecure bool
caFile string
timeout string
}

// Values returns a slice of flag values to pass to kubectl.
func (f KubectlFlags) Values() []string {
var v []string
if f.kubeConfig != "" {
v = append(v, "--kubeconfig="+f.kubeConfig)
}
if f.cacheDir != "" {
v = append(v, "--cache-dir="+f.cacheDir)
}
if f.certFile != "" {
v = append(v, "--client-certificate="+f.certFile)
}
if f.keyFile != "" {
v = append(v, "--client-key="+f.keyFile)
}
if f.bearerToken != "" {
v = append(v, "--token="+f.bearerToken)
}
if f.impersonate != "" {
v = append(v, "--as="+f.impersonate)
}
if len(f.impersonateGroup) > 0 {
v = append(v, "--as-group="+strings.Join(f.impersonateGroup, ","))
}
if f.username != "" {
v = append(v, "--username="+f.username)
}
if f.password != "" {
v = append(v, "--password="+f.password)
}
if f.clusterName != "" {
v = append(v, "--cluster="+f.clusterName)
}
if f.authInfoName != "" {
v = append(v, "--user="+f.authInfoName)
}
if f.context != "" {
v = append(v, "--context="+f.context)
}
if f.namespace != "" {
v = append(v, "--namespace="+f.namespace)
}
if f.apiServer != "" {
v = append(v, "--server="+f.apiServer)
}
if f.tlsServerName != "" {
v = append(v, "--tls-server-name="+f.tlsServerName)
}
if f.insecure {
v = append(v, "--insecure=true")
}
if f.caFile != "" {
v = append(v, "--certificate-authority="+f.caFile)
}
if f.timeout != "" {
v = append(v, "--request-timeout="+f.timeout)
}
return v
}
67 changes: 35 additions & 32 deletions pkg/commands/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,35 @@ package commands
import (
"errors"
"fmt"
"log"
"os"
"os/exec"
"strings"

"github.com/google/ko/internal"
"github.com/google/ko/pkg/commands/options"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/sync/errgroup"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

const kubectlFlagsWarningTemplate = `NOTICE!
-----------------------------------------------------------------
Passing kubectl global flags to ko directly is deprecated.
Instead of passing:
ko %s ... %s
Pass kubectl global flags separated by "--":
ko %s ... -- %s
For more information see:
https://github.com/google/ko/issues/317
-----------------------------------------------------------------
`

// addApply augments our CLI surface with apply.
func addApply(topLevel *cobra.Command) {
koApplyFlags := []string{}
var kf internal.KubectlFlags
po := &options.PublishOptions{}
fo := &options.FilenameOptions{}
so := &options.SelectorOptions{}
Expand Down Expand Up @@ -60,8 +76,11 @@ func addApply(topLevel *cobra.Command) {
ko apply --local -f config/
# Apply from stdin:
cat config.yaml | ko apply -f -`,
Args: cobra.NoArgs,
cat config.yaml | ko apply -f -
# Any flags passed after '--' are passed to 'kubectl apply' directly:
ko apply -f config -- --namespace=foo --kubeconfig=cfg.yaml
`,
RunE: func(cmd *cobra.Command, args []string) error {
if !isKubectlAvailable() {
return errors.New("error: kubectl is not available. kubectl must be installed to use ko apply")
Expand All @@ -80,25 +99,19 @@ func addApply(topLevel *cobra.Command) {
return fmt.Errorf("error creating publisher: %v", err)
}
defer publisher.Close()
// Create a set of ko-specific flags to ignore when passing through
// kubectl global flags.
ignoreSet := make(map[string]struct{})
for _, s := range koApplyFlags {
ignoreSet[s] = struct{}{}
}

// Filter out ko flags from what we will pass through to kubectl.
kubectlFlags := []string{}
cmd.Flags().Visit(func(flag *pflag.Flag) {
if _, ok := ignoreSet[flag.Name]; !ok {
kubectlFlags = append(kubectlFlags, "--"+flag.Name, flag.Value.String())
}
})

// Issue a "kubectl apply" command reading from stdin,
// to which we will pipe the resolved files.
// to which we will pipe the resolved files, and any
// remaining flags passed after '--'.
argv := []string{"apply", "-f", "-"}
argv = append(argv, kubectlFlags...)
if kflags := kf.Values(); len(kflags) != 0 {
skflags := strings.Join(kflags, " ")
log.Printf(kubectlFlagsWarningTemplate,
"apply", skflags,
"apply", skflags)
argv = append(argv, kflags...)
}
argv = append(argv, args...)
kubectlCmd := exec.CommandContext(ctx, "kubectl", argv...)

// Pass through our environment
Expand Down Expand Up @@ -145,17 +158,7 @@ func addApply(topLevel *cobra.Command) {
options.AddFileArg(apply, fo)
options.AddSelectorArg(apply, so)
options.AddBuildOptions(apply, bo)

// Collect the ko-specific apply flags before registering the kubectl global
// flags so that we can ignore them when passing kubectl global flags through
// to kubectl.
apply.Flags().VisitAll(func(flag *pflag.Flag) {
koApplyFlags = append(koApplyFlags, flag.Name)
})

// Register the kubectl global flags.
kubeConfigFlags := genericclioptions.NewConfigFlags(false)
kubeConfigFlags.AddFlags(apply.Flags())
internal.AddFlags(&kf, apply.Flags())

topLevel.AddCommand(apply)
}
54 changes: 21 additions & 33 deletions pkg/commands/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ package commands
import (
"errors"
"fmt"
"log"
"os"
"os/exec"
"strings"

"github.com/google/ko/internal"
"github.com/google/ko/pkg/commands/options"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/sync/errgroup"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

// addCreate augments our CLI surface with apply.
func addCreate(topLevel *cobra.Command) {
koCreateFlags := []string{}
var kf internal.KubectlFlags
po := &options.PublishOptions{}
fo := &options.FilenameOptions{}
so := &options.SelectorOptions{}
Expand Down Expand Up @@ -60,8 +61,11 @@ func addCreate(topLevel *cobra.Command) {
ko create --local -f config/
# Create from stdin:
cat config.yaml | ko create -f -`,
Args: cobra.NoArgs,
cat config.yaml | ko create -f -
# Any flags passed after '--' are passed to 'kubectl apply' directly:
ko apply -f config -- --namespace=foo --kubeconfig=cfg.yaml
`,
RunE: func(cmd *cobra.Command, args []string) error {
if !isKubectlAvailable() {
return errors.New("error: kubectl is not available. kubectl must be installed to use ko create")
Expand All @@ -80,25 +84,19 @@ func addCreate(topLevel *cobra.Command) {
return fmt.Errorf("error creating publisher: %v", err)
}
defer publisher.Close()
// Create a set of ko-specific flags to ignore when passing through
// kubectl global flags.
ignoreSet := make(map[string]struct{})
for _, s := range koCreateFlags {
ignoreSet[s] = struct{}{}
}

// Filter out ko flags from what we will pass through to kubectl.
kubectlFlags := []string{}
cmd.Flags().Visit(func(flag *pflag.Flag) {
if _, ok := ignoreSet[flag.Name]; !ok {
kubectlFlags = append(kubectlFlags, "--"+flag.Name, flag.Value.String())
}
})

// Issue a "kubectl create" command reading from stdin,
// to which we will pipe the resolved files.
argv := []string{"create", "-f", "-"}
argv = append(argv, kubectlFlags...)
// to which we will pipe the resolved files, and any
// remaining flags passed after '--'.
argv := []string{"apply", "-f", "-"}
if kflags := kf.Values(); len(kflags) != 0 {
skflags := strings.Join(kflags, " ")
log.Printf(kubectlFlagsWarningTemplate,
"create", skflags,
"create", skflags)
argv = append(argv, kflags...)
}
argv = append(argv, args...)
kubectlCmd := exec.CommandContext(ctx, "kubectl", argv...)

// Pass through our environment
Expand Down Expand Up @@ -145,17 +143,7 @@ func addCreate(topLevel *cobra.Command) {
options.AddFileArg(create, fo)
options.AddSelectorArg(create, so)
options.AddBuildOptions(create, bo)

// Collect the ko-specific apply flags before registering the kubectl global
// flags so that we can ignore them when passing kubectl global flags through
// to kubectl.
create.Flags().VisitAll(func(flag *pflag.Flag) {
koCreateFlags = append(koCreateFlags, flag.Name)
})

// Register the kubectl global flags.
kubeConfigFlags := genericclioptions.NewConfigFlags(false)
kubeConfigFlags.AddFlags(create.Flags())
internal.AddFlags(&kf, create.Flags())

topLevel.AddCommand(create)
}
5 changes: 0 additions & 5 deletions vendor/github.com/PuerkitoBio/purell/.gitignore

This file was deleted.

12 changes: 0 additions & 12 deletions vendor/github.com/PuerkitoBio/purell/.travis.yml

This file was deleted.

12 changes: 0 additions & 12 deletions vendor/github.com/PuerkitoBio/purell/LICENSE

This file was deleted.

Loading

0 comments on commit 466dbab

Please sign in to comment.