-
Notifications
You must be signed in to change notification settings - Fork 179
Feature: Add New Command Line Client scbctl #2514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
4b8dcce
Feat: Create new scbctl commnad `scan`
Freedisch c6deca5
Feat: add test cases for `scan` command
Freedisch e017ef2
feat: add CI jobs for scbctl test cases
Freedisch d66e878
add correct license header
Freedisch 67ad3b0
feat: update scan command to receive parameters
Freedisch e733102
update scan test cases for scans parameters
Freedisch 143c210
update: add more test cases for scan parameters and fix failling CIs
Freedisch 241169a
add scan assertions
Freedisch 01ec80f
fix name typo
Freedisch 9b09421
update go version in scbctl CI
Freedisch dd994b8
Add sidecar license file for go sum
J12934 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| // SPDX-FileCopyrightText: the secureCodeBox authors | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| package cmd | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "fmt" | ||
| "strings" | ||
|
|
||
| v1 "github.com/secureCodeBox/secureCodeBox/operator/apis/execution/v1" | ||
| kubernetes "github.com/secureCodeBox/secureCodeBox/scbctl/pkg" | ||
| "github.com/spf13/cobra" | ||
| metav2 "k8s.io/apimachinery/pkg/api/errors" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "k8s.io/apimachinery/pkg/runtime" | ||
| utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||
| "k8s.io/cli-runtime/pkg/genericclioptions" | ||
| ) | ||
|
|
||
| var ( | ||
| kubeconfigArgs = genericclioptions.NewConfigFlags(false) | ||
| clientProvider kubernetes.ClientProvider = &kubernetes.DefaultClientProvider{} | ||
| scheme = runtime.NewScheme() | ||
| ) | ||
|
|
||
| func init() { | ||
| utilruntime.Must(v1.AddToScheme(scheme)) | ||
| ScanCmd.Flags().StringP("namespace", "n", "", "Namespace in which to create the scan") | ||
| } | ||
|
|
||
| var ScanCmd = &cobra.Command{ | ||
| Use: "scan [name] -- [parameters...]", | ||
| Short: "Create a new scanner", | ||
| Long: `Create a new execution (Scan) in the default namespace if no namespace is provided`, | ||
| Example: ` | ||
| # Create a new scan | ||
| scbctl scan nmap | ||
| # Create in a different namespace | ||
| scbctl scan --namespace foobar nmap -- scanme.nmap.org -p 90 | ||
| `, | ||
| SilenceUsage: true, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
|
|
||
| scanName := args[0] | ||
| paramIndex := cmd.ArgsLenAtDash() | ||
| if paramIndex == -1 { | ||
| return errors.New("You must use '--' to separate scan parameters") | ||
| } | ||
|
|
||
| parameters := args[paramIndex:] | ||
|
|
||
| fmt.Println("🎬 Initializing Kubernetes client") | ||
|
|
||
| kubeclient, namespace, err := clientProvider.GetClient(kubeconfigArgs) | ||
| if err != nil { | ||
| return fmt.Errorf("Error initializing Kubernetes client: %s", err) | ||
| } | ||
|
|
||
| if namespaceFlag, err := cmd.Flags().GetString("namespace"); err == nil && namespaceFlag != "" { | ||
| namespace = namespaceFlag | ||
| } | ||
|
|
||
| fmt.Printf("🆕 Creating a new scan with name '%s' and parameters '%s'\n", scanName, strings.Join(parameters, " ")) | ||
|
|
||
| scan := &v1.Scan{ | ||
| TypeMeta: metav1.TypeMeta{ | ||
| Kind: "Scan", | ||
| APIVersion: "execution.securecodebox.io/v1", | ||
| }, | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: scanName, | ||
| Namespace: namespace, | ||
| }, | ||
| Spec: v1.ScanSpec{ | ||
| ScanType: scanName, | ||
| Parameters: parameters, | ||
| }, | ||
| } | ||
|
|
||
| fmt.Println("🔁 Launching the scan") | ||
|
|
||
| err = kubeclient.Create(context.TODO(), scan) | ||
| if err != nil { | ||
| if metav2.IsNotFound(err) { | ||
| return fmt.Errorf("failed to create Scan: namespace '%s' not found", namespace) | ||
| } | ||
| return fmt.Errorf("Failed to create Scan: %s", err) | ||
| } | ||
|
|
||
| fmt.Printf("🚀 Successfully created a new Scan '%s'\n", args[0]) | ||
| return nil | ||
|
|
||
| }, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| // SPDX-FileCopyrightText: the secureCodeBox authors | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| package cmd | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "testing" | ||
|
|
||
| v1 "github.com/secureCodeBox/secureCodeBox/operator/apis/execution/v1" | ||
| "github.com/spf13/cobra" | ||
| "k8s.io/apimachinery/pkg/runtime" | ||
| utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||
| "k8s.io/cli-runtime/pkg/genericclioptions" | ||
| "sigs.k8s.io/controller-runtime/pkg/client" | ||
| "sigs.k8s.io/controller-runtime/pkg/client/fake" | ||
| ) | ||
|
|
||
| type MockClientProvider struct { | ||
| client.Client | ||
| namespace string | ||
| err error | ||
| } | ||
|
|
||
| func (m *MockClientProvider) GetClient(_ *genericclioptions.ConfigFlags) (client.Client, string, error) { | ||
| return m.Client, m.namespace, m.err | ||
| } | ||
|
|
||
| func TestScanCommand(t *testing.T) { | ||
| scheme := runtime.NewScheme() | ||
| utilruntime.Must(v1.AddToScheme(scheme)) | ||
|
|
||
| testcases := []struct { | ||
| name string | ||
| args []string | ||
| expectedError error | ||
| }{ | ||
| { | ||
| name: "Valid entry ", | ||
| args: []string{"nmap", "--", "scanme.nmap.org"}, | ||
| expectedError: nil, | ||
| }, | ||
| { | ||
| name: "Valid entry with multiple parameters", | ||
| args: []string{"nmap", "--", "scanme.nmap.org", "-p", "90"}, | ||
| expectedError: nil, | ||
| }, | ||
| { | ||
| name: "Valid entry with namespace", | ||
| args: []string{"scan", "--namespace", "foobar", "nmap", "--", "scanme.nmap.org"}, | ||
| expectedError: nil, | ||
| }, | ||
| { | ||
| name: "No scan parameters provided", | ||
| args: []string{"nmap"}, | ||
| expectedError: errors.New("You must use '--' to separate scan parameters"), | ||
| }, | ||
| } | ||
|
|
||
| for _, tc := range testcases { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| client := fake.NewClientBuilder().WithScheme(scheme).Build() | ||
| clientProvider = &MockClientProvider{ | ||
J12934 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Client: client, | ||
| namespace: "default", | ||
| err: nil, | ||
| } | ||
|
|
||
| cmd := &cobra.Command{ | ||
| Use: ScanCmd.Use, | ||
| Short: ScanCmd.Short, | ||
| Long: ScanCmd.Long, | ||
| Example: ScanCmd.Example, | ||
| RunE: ScanCmd.RunE, | ||
| } | ||
|
|
||
| cmd.Flags().AddFlagSet(ScanCmd.Flags()) | ||
|
|
||
| cmd.SetArgs(tc.args) | ||
| cmd.SilenceUsage = true | ||
|
|
||
| err := cmd.Execute() | ||
| if tc.expectedError != nil { | ||
| if err == nil || err.Error() != tc.expectedError.Error() { | ||
| t.Errorf("expected error: %v, got: %v", tc.expectedError, err) | ||
| } | ||
| } else if err != nil { | ||
| t.Errorf("expected no error, but got: %v", err) | ||
| } | ||
|
|
||
| if tc.expectedError == nil { | ||
| scans := &v1.ScanList{} | ||
| if listErr := client.List(context.Background(), scans); listErr != nil { | ||
| t.Fatalf("failed to list scans: %v", listErr) | ||
| } | ||
| if len(scans.Items) != 1 { | ||
| t.Fatalf("expected 1 scan to created but got %d", len(scans.Items)) | ||
| } | ||
| } | ||
|
|
||
| }) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // SPDX-FileCopyrightText: the secureCodeBox authors | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| module github.com/secureCodeBox/secureCodeBox/scbctl | ||
|
|
||
| go 1.22.0 | ||
|
|
||
| toolchain go1.22.3 | ||
|
|
||
| require sigs.k8s.io/controller-runtime v0.18.4 | ||
|
|
||
| require ( | ||
| github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect | ||
| github.com/davecgh/go-spew v1.1.1 // indirect | ||
| github.com/emicklei/go-restful/v3 v3.11.0 // indirect | ||
| github.com/evanphx/json-patch v5.6.0+incompatible // indirect | ||
| github.com/evanphx/json-patch/v5 v5.9.0 // indirect | ||
| github.com/go-errors/errors v1.4.2 // indirect | ||
| github.com/go-logr/logr v1.4.1 // indirect | ||
| github.com/go-openapi/jsonpointer v0.19.6 // indirect | ||
| github.com/go-openapi/jsonreference v0.20.2 // indirect | ||
| github.com/go-openapi/swag v0.22.3 // indirect | ||
| github.com/gogo/protobuf v1.3.2 // indirect | ||
| github.com/golang/protobuf v1.5.4 // indirect | ||
| github.com/google/btree v1.0.1 // indirect | ||
| github.com/google/gnostic-models v0.6.8 // indirect | ||
| github.com/google/gofuzz v1.2.0 // indirect | ||
| github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect | ||
| github.com/google/uuid v1.3.0 // indirect | ||
| github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect | ||
| github.com/imdario/mergo v0.3.12 // indirect | ||
| github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
| github.com/josharian/intern v1.0.0 // indirect | ||
| github.com/json-iterator/go v1.1.12 // indirect | ||
| github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect | ||
| github.com/mailru/easyjson v0.7.7 // indirect | ||
| github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect | ||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
| github.com/modern-go/reflect2 v1.0.2 // indirect | ||
| github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect | ||
| github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect | ||
| github.com/peterbourgon/diskv v2.0.1+incompatible // indirect | ||
| github.com/pkg/errors v0.9.1 // indirect | ||
| github.com/secureCodeBox/secureCodeBox/operator v0.0.0-20240603123116-d52caf587550 | ||
| github.com/spf13/cobra v1.7.0 // indirect | ||
| github.com/spf13/pflag v1.0.5 // indirect | ||
| github.com/xlab/treeprint v1.2.0 // indirect | ||
| go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect | ||
| golang.org/x/net v0.23.0 // indirect | ||
| golang.org/x/oauth2 v0.12.0 // indirect | ||
| golang.org/x/sync v0.6.0 // indirect | ||
| golang.org/x/sys v0.18.0 // indirect | ||
| golang.org/x/term v0.18.0 // indirect | ||
| golang.org/x/text v0.14.0 // indirect | ||
| golang.org/x/time v0.3.0 // indirect | ||
| google.golang.org/appengine v1.6.7 // indirect | ||
| google.golang.org/protobuf v1.33.0 // indirect | ||
| gopkg.in/inf.v0 v0.9.1 // indirect | ||
| gopkg.in/yaml.v2 v2.4.0 // indirect | ||
| gopkg.in/yaml.v3 v3.0.1 // indirect | ||
| k8s.io/api v0.30.1 // indirect | ||
| k8s.io/apimachinery v0.30.1 // indirect | ||
| k8s.io/cli-runtime v0.30.1 // indirect | ||
| k8s.io/client-go v0.30.1 // indirect | ||
| k8s.io/klog/v2 v2.120.1 // indirect | ||
| k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect | ||
| k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect | ||
| sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect | ||
| sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect | ||
| sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect | ||
| sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect | ||
| sigs.k8s.io/yaml v1.3.0 // indirect | ||
| ) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.