Skip to content

Commit

Permalink
Merge pull request #8 from aep-dev/first
Browse files Browse the repository at this point in the history
Creates + Reads are working
  • Loading branch information
rambleraptor authored Jan 14, 2025
2 parents 607752b + 408b3db commit cb046bc
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 105 deletions.
90 changes: 43 additions & 47 deletions internal/provider/client.go
Original file line number Diff line number Diff line change
@@ -1,59 +1,75 @@
package provider

import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"

"github.com/aep-dev/aep-lib-go/pkg/api"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

func Create(r *api.Resource, c *http.Client, serverUrl string, body map[string]interface{}) error {
func Create(ctx context.Context, r *api.Resource, c *http.Client, serverUrl string, body map[string]interface{}) (map[string]interface{}, error) {
suffix := ""
if r.CreateMethod.SupportsUserSettableCreate {
id, ok := body["id"]
if !ok {
return fmt.Errorf("id field not found in %v", body)
return nil, fmt.Errorf("id field not found in %v", body)
}
idString, ok := id.(string)
if !ok {
return fmt.Errorf("id field is not string %v", id)
return nil, fmt.Errorf("id field is not string %v", id)
}

suffix = fmt.Sprintf("?id=", idString)
suffix = fmt.Sprintf("?id=%s", idString)
}
url, err := createBase(r, body, serverUrl, suffix)
url, err := createBase(ctx, r, body, serverUrl, suffix)
if err != nil {
return err
return nil, err
}

jsonBody, err := json.Marshal(body)
if err != nil {
return fmt.Errorf("error marshalling JSON: %v", err)
return nil, fmt.Errorf("error marshalling JSON: %v", err)
}

req, err := http.NewRequest("POST", url, strings.NewReader(string(jsonBody)))
if err != nil {
return fmt.Errorf("error creating post request: %v", err)
return nil, fmt.Errorf("error creating post request: %v", err)
}

_, err = c.Do(req)
return err
resp, err := c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response body: %v", err)
}
tflog.Info(ctx, fmt.Sprintf("Response body: %q", string(respBody)))
var data map[string]interface{}
err = json.Unmarshal(respBody, &data)
if err != nil {
return nil, err
}
return data, nil
}

func Read(r *api.Resource, c *http.Client, serverUrl string, parameters map[string]interface{}) (map[string]interface{}, error) {
id, ok := parameters["id"]
func Read(ctx context.Context, r *api.Resource, c *http.Client, serverUrl string, parameters map[string]interface{}) (map[string]interface{}, error) {
id, ok := parameters["path"]
if !ok {
return nil, fmt.Errorf("id field not found in %v", parameters)
return nil, fmt.Errorf("path field not found in %v", parameters)
}
idString, ok := id.(string)
if !ok {
return nil, fmt.Errorf("id field is not string %v", id)
return nil, fmt.Errorf("path field is not string %v", id)
}

url, err := createBase(r, parameters, serverUrl, fmt.Sprintf("/%s", idString))
url, err := createBase(ctx, r, parameters, serverUrl, fmt.Sprintf("/%s", idString))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -83,17 +99,17 @@ func Read(r *api.Resource, c *http.Client, serverUrl string, parameters map[stri
return data, nil
}

func Delete(r *api.Resource, c *http.Client, serverUrl string, parameters map[string]interface{}) error {
id, ok := parameters["id"]
func Delete(ctx context.Context, r *api.Resource, c *http.Client, serverUrl string, parameters map[string]interface{}) error {
id, ok := parameters["path"]
if !ok {
return fmt.Errorf("id field not found in %v", parameters)
return fmt.Errorf("path field not found in %v", parameters)
}
idString, ok := id.(string)
if !ok {
return fmt.Errorf("id field is not string %v", id)
return fmt.Errorf("path field is not string %v", id)
}

url, err := createBase(r, parameters, serverUrl, fmt.Sprintf("/%s", idString))
url, err := createBase(ctx, r, parameters, serverUrl, fmt.Sprintf("/%s", idString))
if err != nil {
return err
}
Expand All @@ -107,17 +123,17 @@ func Delete(r *api.Resource, c *http.Client, serverUrl string, parameters map[st
return err
}

func Update(r *api.Resource, c *http.Client, serverUrl string, parameters map[string]interface{}) error {
id, ok := parameters["id"]
func Update(ctx context.Context, r *api.Resource, c *http.Client, serverUrl string, parameters map[string]interface{}) error {
id, ok := parameters["path"]
if !ok {
return fmt.Errorf("id field not found in %v", parameters)
return fmt.Errorf("path field not found in %v", parameters)
}
idString, ok := id.(string)
if !ok {
return fmt.Errorf("id field is not string %v", id)
return fmt.Errorf("path field is not string %v", id)
}

url, err := createBase(r, parameters, serverUrl, fmt.Sprintf("/%s", idString))
url, err := createBase(ctx, r, parameters, serverUrl, fmt.Sprintf("/%s", idString))
if err != nil {
return err
}
Expand All @@ -136,26 +152,6 @@ func Update(r *api.Resource, c *http.Client, serverUrl string, parameters map[st
return err
}

func createBase(r *api.Resource, body map[string]interface{}, serverUrl string, suffix string) (string, error) {
pElems := []string{}
for i, p := range r.PatternElems {
// last element, we assume this was handled by the caller.
if i == len(r.PatternElems)-1 {
continue
}
if i%2 == 0 {
pElems = append(pElems, p)
} else {
v, ok := body[p]
if !ok {
return "", fmt.Errorf("%s not found in resource", p)
}
s, ok := v.(string)
if !ok {
return "", fmt.Errorf("%s value %v cannot be converted to string", p, v)
}
pElems = append(pElems, s)
}
}
return serverUrl + "/" + strings.Join(pElems, "/") + suffix, nil
func createBase(ctx context.Context, r *api.Resource, body map[string]interface{}, serverUrl string, suffix string) (string, error) {

Check failure on line 155 in internal/provider/client.go

View workflow job for this annotation

GitHub Actions / Build

`createBase` - `ctx` is unused (unparam)
return serverUrl + "/" + r.Plural + suffix, nil
}
45 changes: 44 additions & 1 deletion internal/provider/data/resource.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

// Inspiration: https://github.com/hashicorp/terraform-plugin-framework/issues/1035#issuecomment-2396927170

package data

import (
"encoding/json"
"errors"

"github.com/hashicorp/terraform-plugin-go/tftypes"
Expand Down Expand Up @@ -40,7 +43,7 @@ type Resource struct {
//
// It assumes the ID value exists and is a string type.
func (r Resource) GetId() string {
return *r.Values["id"].String
return *r.Values["path"].String
}

// WithType adds type information into a Resource as this is not stored as part
Expand Down Expand Up @@ -81,3 +84,43 @@ func (r *Resource) FromTerraform5Value(value tftypes.Value) error {
r.objectType = value.Type().(tftypes.Object)

Check failure on line 84 in internal/provider/data/resource.go

View workflow job for this annotation

GitHub Actions / Build

type assertion must be checked (forcetypeassert)
return nil
}

// The structure of the data is:
//
// {"description": {"string": "my-description"}, "path": {"string": "my-path"}}
//
// This function removes the object type keys.
func (r *Resource) ToJSON() (map[string]interface{}, error) {
jsonData, err := json.Marshal(r.Values)
if err != nil {
return nil, err
}

var jsonDataMap map[string]interface{}
err = json.Unmarshal(jsonData, &jsonDataMap)
if err != nil {
return nil, err
}

// TODO: This is super brittle!
for key, value := range jsonDataMap {
if valueMap, ok := value.(map[string]interface{}); ok {
if stringValue, ok := valueMap["string"]; ok {
jsonDataMap[key] = stringValue
}
}
}

return jsonDataMap, nil
}

// TODO: This is super brittle!
func ToResource(m map[string]interface{}, r *Resource) error {
for k, v := range m {
vString, ok := v.(string)
if ok {
r.Values[k] = Value{String: &vString}
}
}
return nil
}
Loading

0 comments on commit cb046bc

Please sign in to comment.