Skip to content
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

feat(cli): new agent access token command #256

Merged
merged 1 commit into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions api/agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//
// Author:: Salim Afiune Maya (<[email protected]>)
// Copyright:: Copyright 2020, Lacework Inc.
// License:: Apache License, Version 2.0
//
// 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 api

import (
"fmt"
)

// AgentsService is a service that interacts with the Agent Access Tokens
// endpoints from the Lacework Server
type AgentsService struct {
client *Client
}

// ListTokens returns a list of agent access tokens in a Lacework account
func (svc *AgentsService) ListTokens() (response AgentTokensResponse, err error) {
err = svc.client.RequestDecoder("GET", apiAgentTokens, nil, &response)
return
}

// GetToken returns details about an agent access token
func (svc *AgentsService) GetToken(token string) (response AgentTokensResponse, err error) {
err = svc.client.RequestDecoder("GET", fmt.Sprintf(apiAgentTokenFromID, token), nil, &response)
return
}

// CreateToken creates a new agent access token
func (svc *AgentsService) CreateToken(name, desc string) (response AgentTokensResponse, err error) {
err = svc.client.RequestEncoderDecoder("POST",
apiAgentTokens,
AgentTokenRequest{
TokenAlias: name,
Enabled: 1,
Props: AgentTokenProps{
Description: desc,
},
},
&response,
)
return
}

// UpdateToken updates an agent access token with the provided request data
func (svc *AgentsService) UpdateToken(token string, data AgentTokenRequest) (
response AgentTokensResponse,
err error,
) {
err = svc.client.RequestEncoderDecoder("PUT",
fmt.Sprintf(apiAgentTokenFromID, token),
data,
&response,
)
return
}

// UpdateTokenStatus updates only the status of an agent access token (enable or disable)
func (svc *AgentsService) UpdateTokenStatus(token string, enable bool) (
response AgentTokensResponse,
err error,
) {

request := AgentTokenRequest{Enabled: 0}
if enable {
request.Enabled = 1
}
err = svc.client.RequestEncoderDecoder("PUT",
fmt.Sprintf(apiAgentTokenFromID, token),
request,
&response,
)
return
}

type AgentTokensResponse struct {
Data []AgentToken `json:"data"`
Ok bool `json:"ok"`
Message string `json:"message"`
}

type AgentToken struct {
AccessToken string `json:"ACCESS_TOKEN"`
Account string `json:"ACCOUNT"`
LastUpdatedTime *Json16DigitTime `json:"LAST_UPDATED_TIME"`
Props *AgentTokenProps `json:"PROPS,omitempty"`
TokenAlias string `json:"TOKEN_ALIAS"`
Enabled string `json:"TOKEN_ENABLED"`
Version string `json:"VERSION"`
}

// @afiune this API returns a string as a boolean, so we have to do this mokeypatch
func (t AgentToken) PrettyStatus() string {
if t.Enabled == "true" {
return "Enabled"
}
return "Disabled"
}
func (t AgentToken) Status() bool {
return t.Enabled == "true"
}

func (t AgentToken) EnabledInt() int {
if t.Enabled == "true" {
return 1
}
return 0
}

type AgentTokenRequest struct {
TokenAlias string `json:"TOKEN_ALIAS,omitempty"`
Enabled int `json:"TOKEN_ENABLED"`
Props AgentTokenProps `json:"PROPS,omitempty"`
}

type AgentTokenProps struct {
CreatedTime *Json16DigitTime `json:"CREATED_TIME,omitempty"`
Description string `json:"DESCRIPTION,omitempty"`
}
57 changes: 57 additions & 0 deletions api/agent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Author:: Salim Afiune Maya (<[email protected]>)
// Copyright:: Copyright 2020, Lacework Inc.
// License:: Apache License, Version 2.0
//
// 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 api_test

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/lacework/go-sdk/api"
)

func TestAgentTokenPrettyStatus(t *testing.T) {
subject := api.AgentToken{Enabled: "true"}
assert.Equal(t, "Enabled", subject.PrettyStatus())

subject.Enabled = "false"
assert.Equal(t, "Disabled", subject.PrettyStatus())
subject.Enabled = "anything else"
assert.Equal(t, "Disabled", subject.PrettyStatus())
}

func TestAgentTokenStatus(t *testing.T) {
subject := api.AgentToken{Enabled: "true"}
assert.True(t, subject.Status())

subject.Enabled = "false"
assert.False(t, subject.Status())
subject.Enabled = "anything else"
assert.False(t, subject.Status())
}

func TestAgentTokenEnabledInt(t *testing.T) {
subject := api.AgentToken{Enabled: "true"}
assert.Equal(t, 1, subject.EnabledInt())

subject.Enabled = "false"
assert.Equal(t, 0, subject.EnabledInt())
subject.Enabled = "anything else"
assert.Equal(t, 0, subject.EnabledInt())
}
3 changes: 3 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ const (
apiIntegrationSchema = "external/integrations/schema/%s"
apiTokens = "access/tokens"

apiAgentTokens = "external/tokens"
apiAgentTokenFromID = "external/tokens/%s"

apiVulnerabilitiesContainerScan = "external/vulnerabilities/container/repository/images/scan"
apiVulnerabilitiesContainerScanStatus = "external/vulnerabilities/container/reqId/%s"
apiVulnerabilitiesAssessmentFromImageID = "external/vulnerabilities/container/imageId/%s"
Expand Down
2 changes: 2 additions & 0 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Client struct {
headers map[string]string

LQL *LQLService
Agents *AgentsService
Events *EventsService
Compliance *ComplianceService
Integrations *IntegrationsService
Expand Down Expand Up @@ -92,6 +93,7 @@ func NewClient(account string, opts ...Option) (*Client, error) {
c: &http.Client{Timeout: defaultTimeout},
}
c.LQL = &LQLService{c}
c.Agents = &AgentsService{c}
c.Events = &EventsService{c}
c.Compliance = &ComplianceService{c}
c.Integrations = &IntegrationsService{c}
Expand Down
4 changes: 2 additions & 2 deletions cli/cmd/access_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ var (
// accessTokenCmd represents the access-token command
accessTokenCmd = &cobra.Command{
Use: "access-token",
Short: "generate temporary access tokens",
Long: `Generates a temporary access token that can be used to access the
Short: "generate temporary API access tokens",
Long: `Generates a temporary API access token that can be used to access the
Lacework API. The token will be valid for the duration that you specify.`,
Args: cobra.NoArgs,
RunE: generateAccessToken,
Expand Down
Loading