Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Commit d63210e

Browse files
authored
Add Support for TFE Endpoint (#43)
1 parent 1624adb commit d63210e

File tree

143 files changed

+31756
-1950
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+31756
-1950
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## Unreleased
1+
## 0.1.5-alpha (May 20, 2020)
22

3-
* Upgrade go-tfe to v0.7.0 and dependencies
3+
* Upgrade go-tfe to v0.7.0 and dependencies
4+
* Fix issue that prevents SSHKey from being set on new workspaces (#44)
5+
* Add Terraform Enterprise endpoint with `TF_URL` environment variable (#13)
46

57
## 0.1.4-alpha (May 14, 2020)
68

CONTRIBUTING.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ Or to run a specific test in the suite:
4040
go test ./... -run SomeTestFunction_name
4141
```
4242

43+
Example of running specific acceptance tests against Terraform Cloud and Terraform Enterprise:
44+
```shell
45+
export TF_URL="https://my-tfe-hostname"
46+
export TF_ACC=1
47+
export TF_CLI_CONFIG_FILE=$HOME/.terraformrc
48+
export TF_ORG="my-tfe-org"
49+
go test -v ./... -run TestOrganizationTerraformEnterprise
50+
51+
export TF_ORG="my-tfc-org"
52+
go test -v ./... -run TestOrganizationTerraformCloud
53+
```
54+
4355
To create a docker image with your local changes:
4456

4557
```shell

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ dev-tree:
8888
@$(SHELL) $(CURDIR)/build-support/scripts/dev.sh $(DEV_PUSH_ARG)
8989

9090
test:
91-
go test ./...
91+
go test ./... -v
9292

9393
cov:
9494
go test ./... -coverprofile=coverage.out

operator/pkg/controller/workspace/tfc_org.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package workspace
33
import (
44
"context"
55
"fmt"
6+
"net/url"
67
"os"
78

89
tfc "github.com/hashicorp/go-tfe"
@@ -23,21 +24,49 @@ type TerraformCloudClient struct {
2324
SecretsMountPath string
2425
}
2526

27+
func createTerraformConfig(address string, tfConfig *cliconfig.Config) (*tfc.Config, error) {
28+
if len(address) == 0 {
29+
address = tfc.DefaultAddress
30+
}
31+
u, err := url.Parse(address)
32+
if u.Scheme == "" {
33+
return nil, fmt.Errorf("Invalid Terraform Cloud or Enterprise URL. Please specify a scheme (http:// or https://)")
34+
}
35+
if err != nil {
36+
return nil, fmt.Errorf("Not a valid Terraform Cloud or Enterprise URL, %v", err)
37+
}
38+
host := u.Host
39+
if host == "" {
40+
return nil, fmt.Errorf("Terraform Cloud or Enterprise URL hostname is ''. Invalid hostname")
41+
}
42+
43+
if len(tfConfig.Credentials[host]) == 0 {
44+
return nil, fmt.Errorf("Define token for %s", host)
45+
}
46+
47+
return &tfc.Config{
48+
Address: address,
49+
Token: fmt.Sprintf("%v", tfConfig.Credentials[host]["token"]),
50+
}, nil
51+
}
52+
2653
// GetClient creates the configuration for Terraform Cloud
27-
func (t *TerraformCloudClient) GetClient() error {
54+
func (t *TerraformCloudClient) GetClient(tfEndpoint string) error {
2855
tfConfig, diag := cliconfig.LoadConfig()
2956
if diag.Err() != nil {
3057
return diag.Err()
3158
}
3259

33-
config := &tfc.Config{
34-
Token: fmt.Sprintf("%v", tfConfig.Credentials["app.terraform.io"]["token"]),
60+
config, err := createTerraformConfig(tfEndpoint, tfConfig)
61+
if err != nil {
62+
return err
3563
}
3664

3765
client, err := tfc.NewClient(config)
3866
if err != nil {
3967
return diag.Err()
4068
}
69+
4170
t.Client = client
4271
return nil
4372
}

operator/pkg/controller/workspace/tfc_org_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,55 @@ import (
77
"github.com/stretchr/testify/assert"
88
)
99

10+
func setupClient(t *testing.T, tfAddress string) (*TerraformCloudClient, error) {
11+
testOrganization := os.Getenv("TF_ORG")
12+
if os.Getenv("TF_ACC") == "" || os.Getenv("TF_CLI_CONFIG_FILE") == "" {
13+
t.Skipf("this test requires Terraform Cloud and Enterprise access and credentials;" +
14+
"set TF_ACC=1 and TF_CLI_CONFIG_FILE to run it")
15+
}
16+
tfClient := &TerraformCloudClient{
17+
Organization: testOrganization,
18+
}
19+
err := tfClient.GetClient(tfAddress)
20+
return tfClient, err
21+
}
22+
23+
func TestFailsForNonMatchingTerraformEnterpriseHostname(t *testing.T) {
24+
_, err := setupClient(t, "notahostname")
25+
assert.Error(t, err)
26+
}
27+
28+
func TestOrganizationTerraformCloud(t *testing.T) {
29+
tfClient, err := setupClient(t, "")
30+
assert.NoError(t, err)
31+
32+
err = tfClient.CheckOrganization()
33+
assert.NoError(t, err)
34+
}
35+
36+
func TestOrganizationTerraformEnterprise(t *testing.T) {
37+
if os.Getenv("TF_URL") == "" {
38+
t.Skipf("this test requires TF_URL for Terraform Enterprise")
39+
}
40+
tfClient, err := setupClient(t, os.Getenv("TF_URL"))
41+
assert.NoError(t, err)
42+
43+
err = tfClient.CheckOrganization()
44+
assert.NoError(t, err)
45+
}
46+
47+
func TestOrganizationTerraformEnterpriseNotFound(t *testing.T) {
48+
if os.Getenv("TF_URL") == "" {
49+
t.Skipf("this test requires TF_URL for Terraform Enterprise")
50+
}
51+
tfClient, err := setupClient(t, os.Getenv("TF_URL"))
52+
assert.NoError(t, err)
53+
54+
tfClient.Organization = "doesnotexist"
55+
err = tfClient.CheckOrganization()
56+
assert.Error(t, err)
57+
}
58+
1059
func TestShouldGetTerraformVersionFromEnvVariable(t *testing.T) {
1160
expected := "0.11.0"
1261
os.Setenv("TF_VERSION", expected)

operator/pkg/controller/workspace/workspace_controller.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package workspace
33
import (
44
"context"
55
"fmt"
6+
"os"
67
"reflect"
78

89
"github.com/go-logr/logr"
@@ -33,9 +34,10 @@ func Add(mgr manager.Manager) error {
3334
// newReconciler returns a new reconcile.Reconciler
3435
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
3536
tfclient := &TerraformCloudClient{}
36-
err := tfclient.GetClient()
37+
err := tfclient.GetClient(os.Getenv("TF_URL"))
3738
if err != nil {
38-
log.Error(err, "could not create Terraform Cloud client")
39+
log.Error(err, "could not create Terraform Cloud or Enterprise client")
40+
os.Exit(1)
3941
}
4042
return &ReconcileWorkspace{
4143
client: mgr.GetClient(),
@@ -85,13 +87,12 @@ type ReconcileWorkspace struct {
8587

8688
// Reconcile reads that state of the cluster for a Workspace object and makes changes based on the state read
8789
// and what is in the Workspace.Spec
88-
// TODO(user): Modify this Reconcile function to implement your Controller logic. This example creates
89-
// a Pod as an example
9090
// Note:
9191
// The Controller will requeue the Request to be processed again if the returned error is non-nil or
9292
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
9393
func (r *ReconcileWorkspace) Reconcile(request reconcile.Request) (reconcile.Result, error) {
9494
r.reqLogger.WithValues("Name", request.Name, "Namespace", request.Namespace)
95+
9596
// Fetch the Workspace instance
9697
instance := &appv1alpha1.Workspace{}
9798
err := r.client.Get(context.TODO(), request.NamespacedName, instance)
@@ -111,13 +112,13 @@ func (r *ReconcileWorkspace) Reconcile(request reconcile.Request) (reconcile.Res
111112

112113
if err := r.tfclient.CheckOrganization(); err != nil {
113114
r.reqLogger.Error(err, "Could not find organization")
114-
return reconcile.Result{}, nil
115+
return reconcile.Result{}, err
115116
}
116117

117118
r.tfclient.SecretsMountPath = instance.Spec.SecretsMountPath
118119
if err := r.tfclient.CheckSecretsMountPath(); err != nil {
119120
r.reqLogger.Error(err, "Could not find secrets mount path")
120-
return reconcile.Result{}, nil
121+
return reconcile.Result{}, err
121122
}
122123

123124
workspaceID, err := r.tfclient.CheckWorkspace(workspace, instance)

vendor/github.com/apparentlymart/go-textseg/v12/LICENSE

Lines changed: 95 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/apparentlymart/go-textseg/v12/textseg/all_tokens.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)