-
Notifications
You must be signed in to change notification settings - Fork 0
/
follow_via.go
82 lines (72 loc) · 3.14 KB
/
follow_via.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package provider
import (
"errors"
"fmt"
"github.com/nullstone-io/terraform-provider-ns/ns"
"gopkg.in/nullstone-io/go-api-client.v0"
"gopkg.in/nullstone-io/go-api-client.v0/types"
"gopkg.in/nullstone-io/nullstone.v0/workspaces"
"log"
"strings"
)
type ErrViaConnectionNotFound struct {
Workspace types.WorkspaceTarget
Via string
}
// Is implements error wrapping Is(error) bool interface
func (e *ErrViaConnectionNotFound) Is(target error) bool {
var vcnf *ErrViaConnectionNotFound
return errors.As(target, &vcnf)
}
func (e *ErrViaConnectionNotFound) Error() string {
return fmt.Sprintf("via connection (%s) was not found in workspace %s", e.Via, e.Workspace.Id())
}
// walkViaConnection traverses one or many connections to retrieve the target workspace and its connections
// If a via connection contains "/", it will use followViaConnection for each token separated by "/"
func walkViaConnection(nsConfig api.Config, sourceWorkspace types.WorkspaceTarget, connections types.Connections, localConnections workspaces.ManifestConnections, via string) (types.WorkspaceTarget, types.Connections, error) {
curWorkspace, curConnections := sourceWorkspace, connections
for _, via := range strings.Split(via, "/") {
var err error
curWorkspace, curConnections, err = followViaConnection(nsConfig, curWorkspace, curConnections, localConnections, via)
if err != nil {
return curWorkspace, curConnections, fmt.Errorf("error traversing via %q: %w", via, err)
}
}
return curWorkspace, curConnections, nil
}
// followViaConnection traverses a single connection to retrieve the target workspace and its connections
func followViaConnection(nsConfig api.Config, sourceWorkspace types.WorkspaceTarget, connections types.Connections, localConnections workspaces.ManifestConnections, via string) (types.WorkspaceTarget, types.Connections, error) {
viaWorkspace := findViaWorkspace(sourceWorkspace, connections, localConnections, via)
if viaWorkspace == nil {
return sourceWorkspace, connections, &ErrViaConnectionNotFound{Workspace: sourceWorkspace, Via: via}
}
log.Printf("(followViaConnection) Pulling (via=%s) connections for %s", via, viaWorkspace.Id())
viaRunConfig, err := ns.GetWorkspaceConfig(nsConfig, *viaWorkspace)
if err != nil {
return sourceWorkspace, connections, fmt.Errorf("error retrieving connections for `via` workspace (via=%s, workspace=%s): %w", via, viaWorkspace.Id(), err)
}
return *viaWorkspace, viaRunConfig.Connections, nil
}
func findViaWorkspace(sourceWorkspace types.WorkspaceTarget, connections types.Connections, localConnections workspaces.ManifestConnections, via string) *types.WorkspaceTarget {
// 1. Try local connections first
mct, ok := localConnections[via]
if ok {
ct := &types.WorkspaceTarget{
StackId: mct.StackId,
BlockId: mct.BlockId,
EnvId: sourceWorkspace.EnvId,
}
if mct.EnvId != nil {
ct.EnvId = *mct.EnvId
}
return ct
}
// 2. Try connections normally
viaWorkspaceConn, ok := connections[via]
if ok && viaWorkspaceConn.Reference != nil {
ct := sourceWorkspace.FindRelativeConnection(*viaWorkspaceConn.Reference)
return &ct
}
// 3. We can't find the workspace for the connection
return nil
}