-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from silinternational/develop
Release 3.5.0 - New library functions for Run Triggers
- Loading branch information
Showing
7 changed files
with
191 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package lib | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/Jeffail/gabs/v2" | ||
) | ||
|
||
type RunTriggerConfig struct { | ||
WorkspaceID string | ||
SourceWorkspaceID string | ||
} | ||
|
||
func CreateRunTrigger(config RunTriggerConfig) error { | ||
u := NewTfcUrl("/workspaces/" + config.WorkspaceID + "/run-triggers") | ||
payload := buildRunTriggerPayload(config.SourceWorkspaceID) | ||
_ = callAPI(http.MethodPost, u.String(), payload, nil) | ||
return nil | ||
} | ||
|
||
func buildRunTriggerPayload(sourceWorkspaceID string) string { | ||
data := gabs.New() | ||
_, err := data.Object("data") | ||
if err != nil { | ||
return "unable to create run trigger payload:" + err.Error() | ||
} | ||
|
||
workspaceObject := gabs.Wrap(map[string]any{ | ||
"type": "workspaces", | ||
"id": sourceWorkspaceID, | ||
}) | ||
if _, err = data.SetP(workspaceObject, "data.relationships.sourceable.data"); err != nil { | ||
return "unable to complete run trigger payload:" + err.Error() | ||
} | ||
|
||
return data.String() | ||
} | ||
|
||
type FindRunTriggerConfig struct { | ||
SourceWorkspaceID string | ||
WorkspaceID string | ||
} | ||
|
||
// FindRunTrigger searches all the run triggers inbound to the given WorkspaceID. If a run trigger is configured for | ||
// the given SourceWorkspaceID, that trigger is returned. Otherwise, nil is returned. | ||
func FindRunTrigger(config FindRunTriggerConfig) (*RunTrigger, error) { | ||
triggers, err := ListRunTriggers(ListRunTriggerConfig{ | ||
WorkspaceID: config.WorkspaceID, | ||
Type: "inbound", | ||
}) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to list run triggers: %w", err) | ||
} | ||
for _, t := range triggers { | ||
if t.SourceID == config.SourceWorkspaceID { | ||
return &t, nil | ||
} | ||
} | ||
return nil, nil | ||
} | ||
|
||
type RunTrigger struct { | ||
CreatedAt time.Time | ||
SourceName string | ||
SourceID string | ||
WorkspaceName string | ||
WorkspaceID string | ||
} | ||
|
||
type ListRunTriggerConfig struct { | ||
WorkspaceID string | ||
Type string // must be either "inbound" or "outbound" | ||
} | ||
|
||
// ListRunTriggers returns a list of run triggers configured for the given workspace | ||
// https://developer.hashicorp.com/terraform/cloud-docs/api-docs/run-triggers#list-run-triggers | ||
func ListRunTriggers(config ListRunTriggerConfig) ([]RunTrigger, error) { | ||
u := NewTfcUrl("/workspaces/" + config.WorkspaceID + "/run-triggers") | ||
u.SetParam(paramFilterRunTriggerType, config.Type) | ||
|
||
resp := callAPI(http.MethodGet, u.String(), "", nil) | ||
triggers, err := parseRunTriggerListResponse(resp.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return triggers, nil | ||
} | ||
|
||
func parseRunTriggerListResponse(r io.Reader) ([]RunTrigger, error) { | ||
parsed, err := gabs.ParseJSONBuffer(r) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse response data: %w", err) | ||
} | ||
|
||
attributes := parsed.Search("data", "*").Children() | ||
triggers := make([]RunTrigger, len(attributes)) | ||
for i, attr := range attributes { | ||
trigger := RunTrigger{ | ||
SourceID: attr.Path("relationships.sourceable.data.id").Data().(string), | ||
SourceName: attr.Path("attributes.sourceable-name").Data().(string), | ||
WorkspaceID: attr.Path("relationships.workspace.data.id").Data().(string), | ||
WorkspaceName: attr.Path("attributes.workspace-name").Data().(string), | ||
} | ||
createdAt, _ := time.Parse(time.RFC3339, attr.Path("attributes.created-at").Data().(string)) | ||
trigger.CreatedAt = createdAt | ||
triggers[i] = trigger | ||
} | ||
return triggers, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package lib | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func Test_buildRunTriggerPayload(t *testing.T) { | ||
got := buildRunTriggerPayload("ws_id") | ||
if got != `{"data":{"relationships":{"sourceable":{"data":{"id":"ws_id","type":"workspaces"}}}}}` { | ||
t.Fatalf("did not get expected result, got %s", got) | ||
} | ||
} | ||
|
||
func Test_parseRunTriggerListResponse(t *testing.T) { | ||
r := bytes.NewReader([]byte(listTriggerSampleBody)) | ||
triggers, err := parseRunTriggerListResponse(r) | ||
require.NoError(t, err) | ||
require.Equal(t, triggers[0].WorkspaceID, "ws-abcdefghijklmnop") | ||
require.Equal(t, triggers[0].SourceID, "ws-qrstuvwxyzABCDEF") | ||
require.Equal(t, triggers[0].WorkspaceName, "a-workspace-name") | ||
require.Equal(t, triggers[0].SourceName, "source-ws-1") | ||
require.Equal(t, triggers[0].CreatedAt, time.Date(2023, 6, 20, 8, 56, 50, 996e6, time.UTC)) | ||
} | ||
|
||
const listTriggerSampleBody = `{ | ||
"data": [ | ||
{ | ||
"id": "rt-abcdefghijklmnop", | ||
"type": "run-triggers", | ||
"attributes": { | ||
"workspace-name": "a-workspace-name", | ||
"sourceable-name": "source-ws-1", | ||
"created-at": "2023-06-20T08:56:50.996Z" | ||
}, | ||
"relationships": { | ||
"workspace": { | ||
"data": { | ||
"id": "ws-abcdefghijklmnop", | ||
"type": "workspaces" | ||
} | ||
}, | ||
"sourceable": { | ||
"data": { | ||
"id": "ws-qrstuvwxyzABCDEF", | ||
"type": "workspaces" | ||
} | ||
} | ||
} | ||
} | ||
] | ||
}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package lib | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestNewTfcUrl(t *testing.T) { | ||
orgs := NewTfcUrl("/organizations") | ||
require.Equal(t, baseURL+"/organizations", orgs.String()) | ||
|
||
withQuery := NewTfcUrl("/organizations?q=foo") | ||
require.Equal(t, baseURL+"/organizations", withQuery.String()) | ||
} |