diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index e2565ee..94975d7 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -25,6 +25,7 @@ var ( serializer *kjson.Serializer scanTimeOut int scanURL string + kubeContext string // kubernetes context to use that is present in the kubeconfig ) func Execute() { @@ -33,8 +34,13 @@ func Execute() { rootCmd.PersistentFlags().IntVarP(&scanTimeOut, "timeout", "t", 120, "Scan timeout in seconds") rootCmd.PersistentFlags().StringVarP(&scanURL, "url", "u", "https://v2.kubesec.io", "URL to send the request for scanning") rootCmd.PersistentFlags().StringVarP(&kubeconfig, "kubeconfig", "k", "", "Path to kubeconfig, overrides KUBECONFIG environment variable") + rootCmd.PersistentFlags().StringVarP(&kubeContext, "context", "c", "", "kubernetes context to use in kubeconfig") - serializer = kjson.NewYAMLSerializer(kjson.DefaultMetaFactory, scheme.Scheme, scheme.Scheme) + //serializer = kjson.NewYAMLSerializer(kjson.DefaultMetaFactory, scheme.Scheme, scheme.Scheme) + + serializer = kjson.NewSerializerWithOptions(kjson.DefaultMetaFactory, scheme.Scheme, scheme.Scheme, kjson.SerializerOptions{ + Yaml: true, + }) // commands rootCmd.AddCommand(versionCmd) @@ -56,6 +62,7 @@ func newKubeClient(kubeconfig string) (*kubernetes.Clientset, error) { } clientset, err := kubernetes.NewForConfig(config) + if err != nil { return nil, fmt.Errorf("Unable to create a new Clienset: %w", err) } @@ -73,6 +80,11 @@ func newClientConfig(kubeconfig string) (*rest.Config, error) { configOverrides := &clientcmd.ConfigOverrides{} + // if kubeContext is not empty, it will override the current context + if kubeContext != "" { + configOverrides.CurrentContext = kubeContext + } + kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) config, err := kubeConfig.ClientConfig() diff --git a/pkg/kubesec/kubesec.go b/pkg/kubesec/kubesec.go index 49f79f8..459f8e9 100644 --- a/pkg/kubesec/kubesec.go +++ b/pkg/kubesec/kubesec.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "strings" "time" @@ -29,56 +28,56 @@ func NewClient(url string, timeOutSec int) *KubesecClient { // ScanDefinition scans the provided resource definition. func (kc *KubesecClient) ScanDefinition(def bytes.Buffer) (KubeSecResults, error) { - + ctx := context.Background() - + ctx, cancel := context.WithTimeout(ctx, time.Duration(kc.TimeOutSec)*time.Second) - + defer cancel() - + req, err := http.NewRequestWithContext(ctx, http.MethodPost, kc.URL, &def) - + if err != nil { return nil, err } - + contentType := "application/x-www-form-urlencoded" - + req.Header.Set("Content-Type", contentType) - + client := &http.Client{} - + resp, err := client.Do(req.WithContext(ctx)) - + if err != nil { return nil, err } - + defer resp.Body.Close() - + if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("got %v response from %v instead of 200 OK", resp.StatusCode, kc.URL) } - - body, err := ioutil.ReadAll(resp.Body) - + + body, err := io.ReadAll(resp.Body) + if err != nil { return nil, err } - + if len(body) < 1 { return nil, errors.New("failed to scan definition") } - + // API version v2 of Kubesec available at https://v2.kubesec.io returns a slice of results var results []KubesecResult - + err = json.Unmarshal(body, &results) - + if err != nil { return nil, err } - + return results, nil } @@ -111,7 +110,7 @@ func (r *KubesecResult) Dump(w io.Writer) { if len(el.Reason) > 0 { fmt.Fprintln(w, el.Reason) } - + } fmt.Fprintln(w, "-----------------") }