From 7071a77e456d0ea0a929f2b7c2bc3f4902877feb Mon Sep 17 00:00:00 2001 From: trend-lucas-wu <153708950+trend-lucas-wu@users.noreply.github.com> Date: Fri, 30 Aug 2024 09:20:03 +0800 Subject: [PATCH] add k8s cluster move group feature, enhance error response message (#7) --- README.md | 16 ++++++-- docs/resources/container_cluster.md | 4 +- .../visionone_container_cluster/resource.tf | 2 +- internal/trendmicro/client.go | 41 +++++++++---------- .../container_security/resources/cluster.go | 9 ++-- pkg/dto/request.go | 1 + 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index e6b9ee0..da5c95e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Our Terraform Provider: https://registry.terraform.io/providers/trendmicro/visio ## Local Development Setup ### For Mac User -create .terraformrc file under your home dire(~) +create .terraformrc file under your home directory(~) ### 1. Setup $GOBIN Verify with @@ -17,7 +17,15 @@ go env GOBIN ``` make sure you have the path ready. -If nothing setup GOBIN with default /Users//go/bin +If nothing setup GOBIN with default /Users/YOUR_USERNAME/go/bin + +### 2. Overrides local provider + +check your provider installation setting in ~/.terraformrc + +```shell +cat ~/.terraformrc +``` ```shell provider_installation { @@ -34,7 +42,7 @@ provider_installation { } ``` -### 2. Compile Provider Code +### 3. Compile Provider Code ```shell go install . @@ -42,7 +50,7 @@ go install . The binary executive file will store at your $GOBIN -### 3. Verify with Terraform +### 4. Verify with Terraform Either find sample code under example folder or make your own ```terraform diff --git a/docs/resources/container_cluster.md b/docs/resources/container_cluster.md index 0d46e16..e15aeb5 100644 --- a/docs/resources/container_cluster.md +++ b/docs/resources/container_cluster.md @@ -19,7 +19,7 @@ resource "visionone_container_cluster" "example_cluster" { description = "This is a sample cluster" resource_id = "arn:aws:eks:xxx:xxx:cluster/xxx" policy_id = "LogOnlyPolicy-xxx" - group_id = "00000000-0000-0000-0000-000000000000" + group_id = "00000000-0000-0000-0000-000000000001" runtime_security_enabled = true vulnerability_scan_enabled = true namespaces = ["kube-system"] @@ -99,7 +99,7 @@ resource "helm_release" "trendmicro" { ### Required -- `group_id` (String) The ID of the group associated with the cluster. To get the group ID, go to Container Security > Container Inventory on the Trend Vision One console. +- `group_id` (String) The ID of the group associated with the cluster. To get IDs of the groups within the user's management scope, use the Kubernetes cluster groups API to list these IDs. - `name` (String) The name of the cluster. ### Optional diff --git a/examples/resources/visionone_container_cluster/resource.tf b/examples/resources/visionone_container_cluster/resource.tf index 899dbf5..3dcdfa3 100644 --- a/examples/resources/visionone_container_cluster/resource.tf +++ b/examples/resources/visionone_container_cluster/resource.tf @@ -3,7 +3,7 @@ resource "visionone_container_cluster" "example_cluster" { description = "This is a sample cluster" resource_id = "arn:aws:eks:xxx:xxx:cluster/xxx" policy_id = "LogOnlyPolicy-xxx" - group_id = "00000000-0000-0000-0000-000000000000" + group_id = "00000000-0000-0000-0000-000000000001" runtime_security_enabled = true vulnerability_scan_enabled = true namespaces = ["kube-system"] diff --git a/internal/trendmicro/client.go b/internal/trendmicro/client.go index caaf475..9f548d5 100644 --- a/internal/trendmicro/client.go +++ b/internal/trendmicro/client.go @@ -1,6 +1,8 @@ package trendmicro import ( + "bytes" + "encoding/json" "errors" "fmt" "io" @@ -73,16 +75,13 @@ func (c *Client) DoRequest(req *http.Request) (body []byte, err error) { switch res.StatusCode { case http.StatusOK, http.StatusCreated, http.StatusNoContent: return body, nil - case http.StatusBadRequest: - return nil, fmt.Errorf("%w trace id: %s", dto.ErrorBadRequest, res.Header.Get("x-trace-id")) - case http.StatusUnauthorized: - return nil, fmt.Errorf("%w trace id: %s", dto.Unauthorized, res.Header.Get("x-trace-id")) - case http.StatusForbidden: - return nil, fmt.Errorf("%w trace id: %s", dto.ErrorForbidden, res.Header.Get("x-trace-id")) - case http.StatusNotFound: - return nil, fmt.Errorf("%w trace id: %s", dto.ErrorNotFound, res.Header.Get("x-trace-id")) - case StatusVisionOneInnerError: - return nil, fmt.Errorf("%w trace id: %s", errors.New(string(body)), res.Header.Get("x-trace-id")) + case http.StatusBadRequest, http.StatusUnauthorized, http.StatusForbidden, http.StatusNotFound, StatusVisionOneInnerError: + var out bytes.Buffer + err = json.Indent(&out, body, "", " ") + if err != nil { + return nil, err + } + return nil, fmt.Errorf("\n%w \nTrace id: %s", errors.New(out.String()), res.Header.Get("x-trace-id")) default: return nil, fmt.Errorf("%w trace id: %s", dto.ErrorInternal, res.Header.Get("x-trace-id")) } @@ -101,23 +100,21 @@ func (c *Client) DoRequestWithFullResponse(req *http.Request) (*http.Response, e switch res.StatusCode { case http.StatusOK, http.StatusCreated, http.StatusNoContent: return res, nil - case http.StatusBadRequest: - return nil, fmt.Errorf("%w trace id: %s", dto.ErrorBadRequest, res.Header.Get("x-trace-id")) - case http.StatusUnauthorized: - return nil, fmt.Errorf("%w trace id: %s", dto.Unauthorized, res.Header.Get("x-trace-id")) - case http.StatusForbidden: - return nil, fmt.Errorf("%w trace id: %s", dto.ErrorForbidden, res.Header.Get("x-trace-id")) - case http.StatusNotFound: - return nil, fmt.Errorf("%w trace id: %s", dto.ErrorNotFound, res.Header.Get("x-trace-id")) - case StatusVisionOneInnerError: - body, err := io.ReadAll(res.Body) + case http.StatusNotFound, http.StatusBadRequest, http.StatusUnauthorized, http.StatusForbidden, StatusVisionOneInnerError: defer res.Body.Close() + body, err := io.ReadAll(res.Body) if err != nil { return nil, err } - return nil, fmt.Errorf("%w trace id: %s", errors.New(string(body)), res.Header.Get("x-trace-id")) + + var out bytes.Buffer + err = json.Indent(&out, body, "", " ") + if err != nil { + return nil, err + } + return nil, fmt.Errorf("\n%w \nTrace id: %s", errors.New(out.String()), res.Header.Get("x-trace-id")) default: - return nil, fmt.Errorf("%w trace id: %s", dto.ErrorInternal, res.Header.Get("x-trace-id")) + return nil, fmt.Errorf("%w \nTrace id: %s", dto.ErrorInternal, res.Header.Get("x-trace-id")) } } diff --git a/internal/trendmicro/container_security/resources/cluster.go b/internal/trendmicro/container_security/resources/cluster.go index 64a1cb2..82ab563 100644 --- a/internal/trendmicro/container_security/resources/cluster.go +++ b/internal/trendmicro/container_security/resources/cluster.go @@ -117,11 +117,8 @@ func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re Computed: true, }, "group_id": schema.StringAttribute{ - MarkdownDescription: "The ID of the group associated with the cluster. To get the group ID, go to Container Security > Container Inventory on the Trend Vision One console.", + MarkdownDescription: "The ID of the group associated with the cluster. To get IDs of the groups within the user's management scope, use the Kubernetes cluster groups API to list these IDs.", Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), - }, }, "namespaces": schema.SetAttribute{ ElementType: types.StringType, @@ -347,7 +344,9 @@ func (r *clusterResource) Update(ctx context.Context, req resource.UpdateRequest return } - updateRequest := dto.UpdateClusterRequest{} + updateRequest := dto.UpdateClusterRequest{ + GroupId: plan.GroupId.ValueString(), + } if !plan.Description.IsNull() { updateRequest.Description = plan.Description.ValueString() } diff --git a/pkg/dto/request.go b/pkg/dto/request.go index 0f9eeba..b99a035 100644 --- a/pkg/dto/request.go +++ b/pkg/dto/request.go @@ -38,6 +38,7 @@ type UpdateClusterRequest struct { Description string `json:"description"` PolicyId string `json:"policyId"` ResourceId string `json:"resourceId"` + GroupId string `json:"groupId"` } // Container Security - Policy Request