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

refactor: internal directories and files #44

Merged
merged 1 commit into from
Feb 13, 2023
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/orange-cloudavenue/terraform-provider-cloudavenue
go 1.19

require (
github.com/antihax/optional v1.0.0
github.com/google/uuid v1.3.0
github.com/hashicorp/terraform-plugin-docs v0.13.0
github.com/hashicorp/terraform-plugin-framework v1.1.1
Expand All @@ -19,7 +20,6 @@ require (
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/agext/levenshtein v1.2.2 // indirect
github.com/antihax/optional v1.0.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
Expand Down
71 changes: 71 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package client

import (
"context"
"errors"
"fmt"

apiclient "github.com/orange-cloudavenue/cloudavenue-sdk-go"
)

var (
ErrAuthFailed = errors.New("authentication error")
ErrTokenEmpty = errors.New("token is empty")
)

type CloudAvenue struct {
User string
Org string
Password string
URL string
TerraformVersion string
CloudAvenueVersion string
APIClient *apiclient.APIClient
Auth context.Context
}

// New creates a new CloudAvenue client.
func (c *CloudAvenue) New() (*CloudAvenue, error) {
auth := c.createBasicAuthContext()
cfg := c.createConfiguration()

c.APIClient = apiclient.NewAPIClient(cfg)
_, ret, err := c.APIClient.AuthenticationApi.Cloudapi100SessionsPost(auth)
if err != nil {
return nil, fmt.Errorf("%w : %v", ErrAuthFailed, err)
}
token := ret.Header.Get("x-vmware-vcloud-access-token")
if token == "" {
return nil, ErrTokenEmpty
}

c.Auth = createTokenInContext(token)
return c, nil
}

// createBasicAuthContext creates a new context with the basic auth values.
func (c *CloudAvenue) createBasicAuthContext() context.Context {
// Create a new CloudAvenue client using the configuration values
auth := context.WithValue(context.Background(), apiclient.ContextBasicAuth, apiclient.BasicAuth{
UserName: c.User + "@" + c.Org,
Password: c.Password,
})

return auth
}

// createConfiguration creates a new configuration for the CloudAvenue client.
func (c *CloudAvenue) createConfiguration() *apiclient.Configuration {
cfg := &apiclient.Configuration{
BasePath: c.URL,
DefaultHeader: make(map[string]string),
UserAgent: fmt.Sprintf("Terraform/%s CloudAvenue/%s", c.TerraformVersion, c.CloudAvenueVersion),
}

return cfg
}

// createTokenInContext creates a new context with the token value.
func createTokenInContext(token string) context.Context {
return context.WithValue(context.Background(), apiclient.ContextAccessToken, token)
}
74 changes: 74 additions & 0 deletions internal/client/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package client

import (
"reflect"
"testing"

apiclient "github.com/orange-cloudavenue/cloudavenue-sdk-go"
)

func TestCloudAvenueClient(t *testing.T) {
t.Parallel()
t.Run("CreateBasicAuthContext", func(t *testing.T) {
t.Parallel()

ca := CloudAvenue{
User: "dasilva",
Password: "dasilva",
Org: "acme",
}

authCtx := ca.createBasicAuthContext()
auth, isBasicAuth := authCtx.Value(apiclient.ContextBasicAuth).(apiclient.BasicAuth)
if !isBasicAuth {
t.Fatalf("expected context with cloudavenue.BasicAuth value, got %v", reflect.TypeOf(authCtx.Value(apiclient.ContextBasicAuth)))
}

if auth.UserName != "dasilva@acme" {
t.Fatalf("expected username to be %q, got %q", "dasilva@acme", auth.UserName)
}

if auth.Password != "dasilva" {
t.Fatalf("expected password to be %q, got %q", "dasilva", auth.Password)
}
})

t.Run("CreateConfiguration", func(t *testing.T) {
t.Parallel()

ca := CloudAvenue{
TerraformVersion: "0.13.0",
CloudAvenueVersion: "0.1.0",
URL: "https://console1.cloudavenue.orange-business.com",
}

cfg := ca.createConfiguration()
emptyMap := make(map[string]string)

if cfg.BasePath != "https://console1.cloudavenue.orange-business.com" {
t.Fatalf("expected base path to be %q, got %q", "https://console1.cloudavenue.orange-business.com", cfg.BasePath)
}

if cfg.UserAgent != "Terraform/0.13.0 CloudAvenue/0.1.0" {
t.Fatalf("expected user agent to be %q, got %q", "Terraform/0.13.0 CloudAvenue/0.1.0", cfg.UserAgent)
}

if !reflect.DeepEqual(cfg.DefaultHeader, emptyMap) {
t.Fatalf("expected default header to be %v, got %v", emptyMap, cfg.DefaultHeader)
}
})

t.Run("CreateTokenContext", func(t *testing.T) {
t.Parallel()
authCtx := createTokenInContext("t0k3n")
token, isString := authCtx.Value(apiclient.ContextAccessToken).(string)

if !isString {
t.Fatalf("expected token with string value, got %v", reflect.TypeOf(authCtx.Value(apiclient.ContextAccessToken)))
}

if token != "t0k3n" {
t.Fatalf("expected token to be %s, got %s", "t0k3n", token)
}
})
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package provider
package helpers

import (
"fmt"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package provider
package helpers

import (
"context"
Expand All @@ -7,8 +7,8 @@ import (
apiclient "github.com/orange-cloudavenue/cloudavenue-sdk-go"
)

// getAuthContextWithTO is a helper function to create the auth context with the token api and the terraform context with timeout.
func getAuthContextWithTO(apiCtx, tfCtx context.Context) (context.Context, error) {
// GetAuthContextWithTO is a helper function to create the auth context with the token api and the terraform context with timeout.
func GetAuthContextWithTO(apiCtx, tfCtx context.Context) (context.Context, error) {
token, tokenIsAString := apiCtx.Value(apiclient.ContextAccessToken).(string)
if !tokenIsAString {
return nil, errors.New("token is not a string")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package provider
package helpers

import (
"context"
Expand All @@ -17,7 +17,7 @@ func TestGetAuthContextWithTO(t *testing.T) {
tfCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()

newCtx, _ := getAuthContextWithTO(apiCtx, tfCtx)
newCtx, _ := GetAuthContextWithTO(apiCtx, tfCtx)
newToken, _ := newCtx.Value(apiclient.ContextAccessToken).(string)
if want := "token"; newToken != want {
t.Errorf("%s: got %s, want %s", name, newToken, want)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package provider
package helpers

const (
ForceNewDescription = "Changes to this field will force a new resource to be created."
Expand Down
70 changes: 70 additions & 0 deletions internal/helpers/job.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package helpers

import (
"context"
"strings"

"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client"
)

type JobStatusMessage string

const (
DONE JobStatusMessage = "DONE"
FAILED JobStatusMessage = "FAILED"
CREATED JobStatusMessage = "CREATED"
PENDING JobStatusMessage = "PENDING"
INPROGRESS JobStatusMessage = "IN_PROGRESS"
ERROR JobStatusMessage = "ERROR"
)

// GetJobStatus is a helper function to get the status of a job.
func GetJobStatus(
ctx context.Context,
client *client.CloudAvenue,
jobID string,
) (JobStatusMessage, error) {
jobStatus, _, err := client.APIClient.JobsApi.ApiCustomersV10JobsJobIdGet(ctx, jobID)
if err != nil {
return "", err
}
return parseJobStatus(jobStatus[0].Status), nil
}

// parseJobStatus return the status of a job.
func parseJobStatus(str string) JobStatusMessage {
switch str {
case "DONE":
return DONE
case "FAILED":
return FAILED
case "CREATED":
return CREATED
case "PENDING":
return PENDING
case "IN_PROGRESS":
return INPROGRESS
default:
return ""
}
}

// string is a stringer interface for jobStatus
func (j JobStatusMessage) String() string {
return strings.ToLower(string(j))
}

// isDone is a helper function to check if a job is done.
func (j JobStatusMessage) IsDone() bool {
return j == DONE
}

// JobStatePending is a helper function to return an array of pending states.
func JobStatePending() []string {
return []string{CREATED.String(), INPROGRESS.String(), PENDING.String()}
}

// JobStateDone is a helper function to return an array of done states.
func JobStateDone() []string {
return []string{DONE.String()}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package provider
package edgegw

import (
"context"
Expand All @@ -7,6 +7,9 @@ import (
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client"
"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/helpers"
)

var (
Expand All @@ -19,7 +22,7 @@ func NewEdgeGatewayDataSource() datasource.DataSource {
}

type edgeGatewayDataSource struct {
client *CloudAvenueClient
client *client.CloudAvenue
}

type edgeGatewayDataSourceModel struct {
Expand Down Expand Up @@ -78,12 +81,12 @@ func (d *edgeGatewayDataSource) Configure(ctx context.Context, req datasource.Co
return
}

client, ok := req.ProviderData.(*CloudAvenueClient)
client, ok := req.ProviderData.(*client.CloudAvenue)

if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *CloudAvenueClient, got: %T. Please report this issue to the provider developers.", req.ProviderData),
fmt.Sprintf("Expected *client.CloudAvenue, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
Expand All @@ -102,8 +105,8 @@ func (d *edgeGatewayDataSource) Read(ctx context.Context, req datasource.ReadReq
return
}

gateway, httpR, err := d.client.EdgeGatewaysApi.ApiCustomersV20EdgesEdgeIdGet(d.client.auth, data.EdgeID.ValueString())
if x := CheckAPIError(err, httpR); x != nil {
gateway, httpR, err := d.client.APIClient.EdgeGatewaysApi.ApiCustomersV20EdgesEdgeIdGet(d.client.Auth, data.EdgeID.ValueString())
if x := helpers.CheckAPIError(err, httpR); x != nil {
resp.Diagnostics.Append(x.GetTerraformDiagnostic())
if resp.Diagnostics.HasError() {
return
Expand Down
Loading