Skip to content

Commit 288bdf8

Browse files
authored
Merge pull request #28 from lacework/afiune/cli/mvp
feature(cli): The new lacework-cli MVP
2 parents 7763190 + 9d17b1f commit 288bdf8

File tree

711 files changed

+237924
-257
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

711 files changed

+237924
-257
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.DS_Store
12
.idea
23

34
# vim

Makefile

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
default: ci
22

3-
ci: lint test fmt-check imports-check
4-
5-
export GOFLAGS=-mod=vendor
3+
ci: lint test fmt-check imports-check build-cli-cross-platform
64

75
GOLANGCILINTVERSION?=1.23.8
86
COVERAGEOUT?=coverage.out
97
CLINAME?=lacework-cli
8+
GO_LDFLAGS="-X github.com/lacework/go-sdk/cli/cmd.Version=$(shell cat cli/VERSION) \
9+
-X github.com/lacework/go-sdk/cli/cmd.GitSHA=$(shell git rev-parse HEAD) \
10+
-X github.com/lacework/go-sdk/cli/cmd.BuildTime=$(shell date +%Y%m%d%H%M%S)"
11+
GOFLAGS=-mod=vendor
12+
export GOFLAGS GO_LDFLAGS
1013

1114
prepare: install-tools go-vendor
1215

@@ -37,11 +40,24 @@ fmt-check:
3740
imports-check:
3841
@test -z $(shell goimports -l $(shell go list -f {{.Dir}} ./...))
3942

40-
build-cli:
41-
go build -o bin/$(CLINAME) cli/main.go
42-
@echo
43-
@echo To execute the generated binary run:
44-
@echo " ./bin/$(CLINAME)"
43+
build-cli-cross-platform:
44+
gox -output="bin/$(CLINAME)-{{.OS}}-{{.Arch}}" \
45+
-os="darwin linux windows" \
46+
-arch="amd64 386" \
47+
-ldflags=$(GO_LDFLAGS) \
48+
github.com/lacework/go-sdk/cli
49+
50+
install-cli: build-cli-cross-platform
51+
ifeq (x86_64, $(shell uname -m))
52+
ln -sf bin/$(CLINAME)-$(shell uname -s | tr '[:upper:]' '[:lower:]')-amd64 bin/$(CLINAME)
53+
else
54+
ln -sf bin/$(CLINAME)-$(shell uname -s | tr '[:upper:]' '[:lower:]')-386 bin/$(CLINAME)
55+
endif
56+
@echo "\nUpdate your PATH environment variable to execute the compiled lacework-cli:"
57+
@echo "\n $$ export PATH=\"$(PWD)/bin:$$PATH\"\n"
58+
59+
release-cli: lint fmt-check imports-check test
60+
scripts/lacework_cli_release.sh
4561

4662
install-tools:
4763
ifeq (, $(shell which golangci-lint))
@@ -50,3 +66,6 @@ endif
5066
ifeq (, $(shell which goimports))
5167
go get golang.org/x/tools/cmd/goimports
5268
endif
69+
ifeq (, $(shell which gox))
70+
go get github.com/mitchellh/gox
71+
endif

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,21 @@ Look at the [api/](api/) folder for more documentation.
3333

3434
## Lacework CLI ([`cli`](cli/))
3535

36-
_(work-in-progress)_ The Lacework Command Line Interface.
36+
The Lacework Command Line Interface.
3737

3838
### Basic Usage
3939

40-
Today, you have to first build the CLI by running `make build-cli`, then you will be
41-
able to execute it directly:
40+
Build and install the CLI by running `make install-cli`, the automation will
41+
ask you to update your `PATH` environment variable to execute the compiled
42+
`lacework-cli` binary.
4243
```
43-
$ make build-cli
44-
$ ./bin/lacework-cli
44+
$ make install-cli
45+
46+
# Make sure to update your PATH with the command provided from the above command
47+
48+
$ lacework-cli help
4549
```
50+
Look at the [cli/](cli/) folder for more documentation.
4651

4752
## License and Copyright
4853
Copyright 2020, Lacework Inc.

api/client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,8 @@ func WithURL(baseURL string) Option {
9393
return nil
9494
})
9595
}
96+
97+
// URL returns the base url configured
98+
func (c *Client) URL() string {
99+
return c.baseURL.String()
100+
}

cli/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<img src="https://techally-content.s3-us-west-1.amazonaws.com/public-content/lacework_logo_full.png" width="600">
2+
3+
# `lacework-cli`
4+
5+
The Lacework Command Line Interface is a tool that helps you manage your
6+
Lacework cloud security platform. You can use it to manage compliance
7+
reports, external integrations, vulnerability scans, and other operations.
8+
9+
## Install
10+
11+
### Bash:
12+
```
13+
$ curl https://raw.githubusercontent.com/lacework/go-sdk/master/cli/install.sh | sudo bash
14+
```
15+
16+
### Powershell:
17+
```
18+
C:\> Set-ExecutionPolicy Bypass -Scope Process -Force
19+
C:\> iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/lacework/go-sdk/master/cli/install.ps1'))
20+
```
21+
22+
## Configuration File
23+
24+
The `lacework-cli` looks for a file named `.lacework.toml` inside your home
25+
directory (`$HOME/.lacework.toml`) to access the following parameters:
26+
* `account`: Account subdomain of URL (i.e. `<ACCOUNT>.lacework.net`)
27+
* `api_key`: API Access Key ID
28+
* `api_secret`: API Access Secret Key
29+
30+
31+
An example of a Lacework configuration file:
32+
```toml
33+
account = "example"
34+
api_key = "EXAMPLE_1234567890ABC"
35+
api_secret = "_super_secret_key"
36+
```
37+
38+
You can provide a different configuration file with the option `--config`.
39+
40+
## Basic Usage
41+
Once you have created your configuration file `$HOME/.lacework.toml`,
42+
you are ready to use the Lacework cli, a few basic commands are:
43+
44+
1) List all integration in your account:
45+
```bash
46+
$ lacework-cli integration list
47+
```
48+
1) Use the `api` command to access Lacework's ResfulAPI, for example,
49+
to get details about and specific event:
50+
```bash
51+
$ lacework-cli api get '/external/events/GetEventDetails?EVENT_ID=16700'
52+
```
53+
54+
## Development
55+
To build and install the CLI from source, use the `make install-cli` directive,
56+
this command will ask you to update your `PATH` environment variable to point
57+
to the compiled `lacework-cli` binary.
58+
```
59+
$ make install-cli
60+
61+
# Make sure to update your PATH with the command provided from the above command
62+
63+
$ lacework-cli help
64+
```
65+
66+
## License and Copyright
67+
Copyright 2020, Lacework Inc.
68+
```
69+
Licensed under the Apache License, Version 2.0 (the "License");
70+
you may not use this file except in compliance with the License.
71+
You may obtain a copy of the License at
72+
73+
http://www.apache.org/licenses/LICENSE-2.0
74+
75+
Unless required by applicable law or agreed to in writing, software
76+
distributed under the License is distributed on an "AS IS" BASIS,
77+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78+
See the License for the specific language governing permissions and
79+
limitations under the License.
80+
```

cli/VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.1.0

cli/cmd/api.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//
2+
// Author:: Salim Afiune Maya (<[email protected]>)
3+
// Copyright:: Copyright 2020, Lacework Inc.
4+
// License:: Apache License, Version 2.0
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
19+
package cmd
20+
21+
import (
22+
"fmt"
23+
"strings"
24+
25+
"github.com/pkg/errors"
26+
"github.com/spf13/cobra"
27+
28+
"github.com/lacework/go-sdk/api"
29+
"github.com/lacework/go-sdk/internal/array"
30+
)
31+
32+
var (
33+
// list of valid API methods
34+
validApiMethods = []string{"get", "post", "delete", "patch"}
35+
36+
// data to send for POST/PATCH request
37+
apiData string
38+
39+
// apiCmd represents the api command
40+
apiCmd = &cobra.Command{
41+
Use: "api <method> <path>",
42+
Short: "Helper to call Lacework's ResfulAPI",
43+
Long: `Use this helper to call any available Lacework API endpoint.
44+
45+
An example, list all integrations configured in your account:
46+
47+
lacework-cli api get /external/integrations
48+
49+
For a complete list of available API endpoints visit:
50+
51+
https://<ACCOUNT>.lacework.net/api/v1/external/docs
52+
`,
53+
Args: argsApiValidator,
54+
RunE: runApiCommand,
55+
}
56+
)
57+
58+
func init() {
59+
rootCmd.AddCommand(apiCmd)
60+
61+
apiCmd.Flags().StringVarP(&apiData,
62+
"data", "d", "",
63+
"data to send only for post and patch requests",
64+
)
65+
}
66+
67+
func runApiCommand(cmd *cobra.Command, args []string) error {
68+
switch args[0] {
69+
case "post", "patch":
70+
if apiData == "" {
71+
return fmt.Errorf("missing '--data' parameter for post or patch requests")
72+
}
73+
case "delete", "get":
74+
if apiData != "" {
75+
return fmt.Errorf("use '--data' only for post and patch requests")
76+
}
77+
}
78+
79+
lacework, err := api.NewClient(cli.Account,
80+
api.WithApiKeys(cli.KeyID, cli.Secret),
81+
)
82+
if err != nil {
83+
return errors.Wrap(err, "unable to generate Lacework API client")
84+
}
85+
86+
cli.Log.Debugw("api client generated",
87+
"version", lacework.ApiVersion(),
88+
"base_url", lacework.URL(),
89+
)
90+
91+
response := new(map[string]interface{})
92+
err = lacework.RequestDecoder(
93+
strings.ToUpper(args[0]),
94+
strings.TrimPrefix(args[1], "/"),
95+
strings.NewReader(apiData),
96+
response,
97+
)
98+
if err != nil {
99+
return errors.Wrap(err, "unable to send the request")
100+
}
101+
102+
pretty, err := cli.JsonF.Marshal(*response)
103+
if err != nil {
104+
cli.Log.Debugw("api response", "raw", response)
105+
return errors.Wrap(err, "unable to format json response")
106+
}
107+
108+
fmt.Println(string(pretty))
109+
return nil
110+
}
111+
112+
func argsApiValidator(_ *cobra.Command, args []string) error {
113+
if len(args) != 2 {
114+
return errors.New("requires 2 argument. (method and path)")
115+
}
116+
if !array.ContainsStr(validApiMethods, args[0]) {
117+
return fmt.Errorf(
118+
"invalid method specified: '%s' (valid methods are %s)",
119+
args[0], validApiMethods,
120+
)
121+
}
122+
return nil
123+
}

cli/cmd/integration.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//
2+
// Author:: Salim Afiune Maya (<[email protected]>)
3+
// Copyright:: Copyright 2020, Lacework Inc.
4+
// License:: Apache License, Version 2.0
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
19+
package cmd
20+
21+
import (
22+
"fmt"
23+
24+
"github.com/pkg/errors"
25+
"github.com/spf13/cobra"
26+
27+
"github.com/lacework/go-sdk/api"
28+
)
29+
30+
var (
31+
// integrationCmd represents the integration command
32+
integrationCmd = &cobra.Command{
33+
Use: "integration",
34+
Short: "Manage external integrations",
35+
}
36+
37+
// integrationListCmd represents the list sub-command inside the integration command
38+
instegrationListCmd = &cobra.Command{
39+
Use: "list",
40+
Short: "List all available external integrations",
41+
RunE: func(cmd *cobra.Command, args []string) error {
42+
lacework, err := api.NewClient(cli.Account,
43+
api.WithApiKeys(cli.KeyID, cli.Secret),
44+
)
45+
if err != nil {
46+
return errors.Wrap(err, "unable to generate Lacework API client")
47+
}
48+
49+
cli.Log.Debugw("api client generated",
50+
"version", lacework.ApiVersion(),
51+
"base_url", lacework.URL(),
52+
)
53+
54+
integrations, err := lacework.Integrations.List()
55+
if err != nil {
56+
return errors.Wrap(err, "unable to get integrations")
57+
}
58+
59+
fmt.Println(integrations.String())
60+
return nil
61+
},
62+
}
63+
64+
// integrationCreateCmd represents the create sub-command inside the integration command
65+
instegrationCreateCmd = &cobra.Command{
66+
Use: "create",
67+
Short: "Create an external integrations",
68+
RunE: func(cmd *cobra.Command, args []string) error {
69+
return nil
70+
},
71+
}
72+
73+
// integrationDeleteCmd represents the delete sub-command inside the integration command
74+
instegrationDeleteCmd = &cobra.Command{
75+
Use: "delete",
76+
Short: "Delete an external integrations",
77+
RunE: func(cmd *cobra.Command, args []string) error {
78+
return nil
79+
},
80+
}
81+
)
82+
83+
func init() {
84+
// add the integration command
85+
rootCmd.AddCommand(integrationCmd)
86+
87+
// add sub-commands to the integration command
88+
integrationCmd.AddCommand(instegrationListCmd)
89+
integrationCmd.AddCommand(instegrationCreateCmd)
90+
integrationCmd.AddCommand(instegrationDeleteCmd)
91+
}

0 commit comments

Comments
 (0)