Skip to content

Commit

Permalink
feat(client): Allow agent to send cluster description
Browse files Browse the repository at this point in the history
Allows the user to configure a cluster description to be used during the
cluster registration in the Venafi control plane.

Signed-off-by: Oluwole Fadeyi <[email protected]>
  • Loading branch information
Oluwole Fadeyi committed Feb 5, 2024
1 parent 7832ba2 commit e827acf
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 3 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/juju/errors v1.0.0
github.com/kylelemons/godebug v1.1.0
github.com/maxatome/go-testdeep v1.13.0
github.com/microcosm-cc/bluemonday v1.0.26
github.com/pkg/errors v0.9.1
github.com/pmylund/go-cache v2.1.0+incompatible
github.com/prometheus/client_golang v1.17.0
Expand Down
5 changes: 3 additions & 2 deletions pkg/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ type Config struct {
// OrganizationID within Preflight that will receive the data.
OrganizationID string `yaml:"organization_id"`
// ClusterID is the cluster that the agent is scanning.
ClusterID string `yaml:"cluster_id"`
DataGatherers []DataGatherer `yaml:"data-gatherers"`
ClusterID string `yaml:"cluster_id"`
ClusterDescription string `yaml:"cluster_description"`
DataGatherers []DataGatherer `yaml:"data-gatherers"`
// InputPath replaces DataGatherers with input data file
InputPath string `yaml:"input-path"`
// OutputPath replaces Server with output data file
Expand Down
5 changes: 4 additions & 1 deletion pkg/agent/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,10 @@ func postData(config Config, preflightClient client.Client, readings []*api.Data

if VenafiCloudMode {
// orgID and clusterID are not required for Venafi Cloud auth
err := preflightClient.PostDataReadings("", "", readings)
err := preflightClient.PostDataReadingsWithOptions(readings, client.Options{
ClusterName: config.ClusterID,
ClusterDescription: config.ClusterDescription,
})
if err != nil {
return fmt.Errorf("post to server failed: %+v", err)
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@ import (
)

type (
// Options is the struct describing additional information pertinent to an agent that isn't a data reading
// These fields will then be uploaded together with data readings.
Options struct {
OrgID string
ClusterID string
ClusterName string
ClusterDescription string
}

// The Client interface describes types that perform requests against the Jetstack Secure backend.
Client interface {
PostDataReadings(orgID, clusterID string, readings []*api.DataReading) error
PostDataReadingsWithOptions(readings []*api.DataReading, options Options) error
Post(path string, body io.Reader) (*http.Response, error)
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/client/client_api_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ func NewAPITokenClient(agentMetadata *api.AgentMetadata, apiToken, baseURL strin
}, nil
}

// PostDataReadingsWithOptions uploads the slice of api.DataReading to the Jetstack Secure backend to be processed for later
// viewing in the user-interface.
func (c *APITokenClient) PostDataReadingsWithOptions(readings []*api.DataReading, opts Options) error {
return c.PostDataReadings(opts.OrgID, opts.ClusterID, readings)
}

// PostDataReadings uploads the slice of api.DataReading to the Jetstack Secure backend to be processed for later
// viewing in the user-interface.
func (c *APITokenClient) PostDataReadings(orgID, clusterID string, readings []*api.DataReading) error {
Expand Down
4 changes: 4 additions & 0 deletions pkg/client/client_oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ func NewOAuthClient(agentMetadata *api.AgentMetadata, credentials *OAuthCredenti
}, nil
}

func (c *OAuthClient) PostDataReadingsWithOptions(readings []*api.DataReading, opts Options) error {
return c.PostDataReadings(opts.OrgID, opts.ClusterID, readings)
}

// PostDataReadings uploads the slice of api.DataReading to the Jetstack Secure backend to be processed for later
// viewing in the user-interface.
func (c *OAuthClient) PostDataReadings(orgID, clusterID string, readings []*api.DataReading) error {
Expand Down
4 changes: 4 additions & 0 deletions pkg/client/client_unauthenticated.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func NewUnauthenticatedClient(agentMetadata *api.AgentMetadata, baseURL string)
}, nil
}

func (c *UnauthenticatedClient) PostDataReadingsWithOptions(readings []*api.DataReading, opts Options) error {
return c.PostDataReadings(opts.OrgID, opts.ClusterID, readings)
}

// PostDataReadings uploads the slice of api.DataReading to the Jetstack Secure backend to be processed for later
// viewing in the user-interface.
func (c *UnauthenticatedClient) PostDataReadings(orgID, clusterID string, readings []*api.DataReading) error {
Expand Down
53 changes: 53 additions & 0 deletions pkg/client/client_venafi_cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/ed25519"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
Expand All @@ -25,6 +26,7 @@ import (
"github.com/google/uuid"
"github.com/hashicorp/go-multierror"
"github.com/jetstack/preflight/api"
"github.com/microcosm-cc/bluemonday"
)

type (
Expand Down Expand Up @@ -152,6 +154,57 @@ func (c *VenafiSvcAccountCredentials) IsClientSet() bool {
return c.ClientID != "" && c.PrivateKeyFile != ""
}

// PostDataReadingsWithOptions uploads the slice of api.DataReading to the Venafi Cloud backend to be processed.
// The Options are then passed as URL params in the request
func (c *VenafiCloudClient) PostDataReadingsWithOptions(readings []*api.DataReading, opts Options) error {
payload := api.DataReadingsPost{
AgentMetadata: c.agentMetadata,
DataGatherTime: time.Now().UTC(),
DataReadings: readings,
}
data, err := json.Marshal(payload)
if err != nil {
return err
}

if !strings.HasSuffix(c.uploadPath, "/") {
c.uploadPath = fmt.Sprintf("%s/", c.uploadPath)
}

venafiCloudUploadURL, err := url.Parse(filepath.Join(c.uploadPath, c.uploaderID))
if err != nil {
return err
}

// validate options and send them as URL params
query := venafiCloudUploadURL.Query()
stripHTML := bluemonday.StrictPolicy()
if opts.ClusterName != "" {
query.Add("name", stripHTML.Sanitize(opts.ClusterName))
}
if opts.ClusterDescription != "" {
query.Add("description", base64.RawURLEncoding.EncodeToString([]byte(stripHTML.Sanitize(opts.ClusterDescription))))
}
venafiCloudUploadURL.RawQuery = query.Encode()

res, err := c.Post(venafiCloudUploadURL.String(), bytes.NewBuffer(data))
if err != nil {
return err
}
defer res.Body.Close()

if code := res.StatusCode; code < 200 || code >= 300 {
errorContent := ""
body, err := io.ReadAll(res.Body)
if err == nil {
errorContent = string(body)
}
return fmt.Errorf("received response with status code %d. Body: %s", code, errorContent)
}

return nil
}

// PostDataReadings uploads the slice of api.DataReading to the Venafi Cloud backend to be processed for later
// viewing in the user-interface.
func (c *VenafiCloudClient) PostDataReadings(_ string, _ string, readings []*api.DataReading) error {
Expand Down

0 comments on commit e827acf

Please sign in to comment.