Skip to content

Commit

Permalink
0.4.5 Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
fdevans committed Oct 7, 2023
2 parents d031f61 + 359b003 commit e52133f
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 6 deletions.
32 changes: 30 additions & 2 deletions rundeck/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,22 @@ func Provider() terraform.ResourceProvider {
},
"auth_token": {
Type: schema.TypeString,
Required: true,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("RUNDECK_AUTH_TOKEN", nil),
Description: "Auth token to use with the Rundeck API.",
},
"auth_username": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("RUNDECK_AUTH_USERNAME", nil),
Description: "Username used to request a tiken for the Rundeck API.",
},
"auth_password": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("RUNDECK_AUTH_PASSWORD", nil),
Description: "Password used to request a tiken for the Rundeck API.",
},
},

ResourcesMap: map[string]*schema.Resource{
Expand All @@ -58,7 +70,23 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
return nil, error
}

token := d.Get("auth_token").(string)
_, okToken := d.GetOk("auth_token")
_, okUsername := d.GetOk("auth_username")
_, okPassword := d.GetOk("auth_password")

var token string

if okToken {
token = d.Get("auth_token").(string)
} else if okUsername && okPassword {
t, err := getToken(d)
token = t
if err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("auth_token need to be set of auth_username and auth_password")
}

client := rundeck.NewRundeckWithBaseURI(apiURL.String())
client.Authorizer = &auth.TokenAuthorizer{Token: token}
Expand Down
12 changes: 10 additions & 2 deletions rundeck/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,15 @@ func testAccPreCheck(t *testing.T) {
if v := os.Getenv("RUNDECK_URL"); v == "" {
t.Fatal("RUNDECK_URL must be set for acceptance tests")
}
if v := os.Getenv("RUNDECK_AUTH_TOKEN"); v == "" {
t.Fatal("RUNDECK_AUTH_TOKEN must be set for acceptance tests")

token := os.Getenv("RUNDECK_AUTH_TOKEN")
username := os.Getenv("RUNDECK_AUTH_USERNAME")
password := os.Getenv("RUNDECK_AUTH_PASSWORD")
if !(token != "" || (username != "" && password != "")) {
t.Logf("RUNDECK_AUTH_TOKEN=%s", token)
t.Logf("RUNDECK_AUTH_USERNAME=%s", username)
t.Logf("RUNDECK_AUTH_PASSWORD=%s", password)
t.Fatal("RUNDECK_AUTH_TOKEN must be set for acceptance tests or RUNDECK_AUTH_USERNAME and RUNDECK_AUTH_PASSWORD")
}

}
113 changes: 113 additions & 0 deletions rundeck/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package rundeck

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
"strconv"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

type TokenResp struct {
User string `json:"user"`
Token string `json:"token"`
ID string `json:"id"`
Creator string `json:"creator"`
Name string `json:"name"`
Expiration time.Time `json:"expiration"`
Roles []string `json:"roles"`
Expired bool `json:"expired"`
}

func getToken(d *schema.ResourceData) (string, error) {
urlP, _ := d.Get("url").(string)
apiVersion, _ := d.Get("api_version").(string)
username, _ := d.Get("auth_username").(string)
password, _ := d.Get("auth_password").(string)

return _getToken(urlP, apiVersion, username, password)

}

func _getToken(urlP string, apiVersion string, username string, password string) (string, error) {

secCheckUrlString := fmt.Sprintf("%s/j_security_check", urlP)
secCheckUrl, err := url.Parse(secCheckUrlString)

if err != nil {
return "", err
}

jar, err := cookiejar.New(nil)
if err != nil {
return "", err
}

client := &http.Client{
Jar: jar,
}

data := url.Values{
"j_username": {username},
"j_password": {password},
}
_, err = client.PostForm(secCheckUrl.String(), data)
if err != nil {
return "", err
}

tokenUrlString := fmt.Sprintf("%s/api/%s/tokens", urlP, "43")
tokenUrl, err := url.Parse(tokenUrlString)

if err != nil {
return "", err
}

tokenBody := map[string]interface{}{}
tokenBody["user"] = username
tokenBody["roles"] = []string{"*"}
tokenBody["duration"] = "0"
tokenBody["name"] = "terraform-token"
tokenBodyJson, err := json.Marshal(tokenBody)
if err != nil {
return "", err
}

req, err := http.NewRequest("POST", tokenUrl.String(), bytes.NewBuffer(tokenBodyJson))
if err != nil {
return "", err
}
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")

resp, err := client.Do(req)
if resp.StatusCode < 200 || resp.StatusCode > 299 {
body, _ := ioutil.ReadAll(resp.Body)
return "", fmt.Errorf("statuscode %d\n%s", resp.StatusCode, string(body))
} else if err != nil {
return "", err
}

tokenResp := &TokenResp{}
err = json.NewDecoder(resp.Body).Decode(tokenResp)
if err != nil {
return "", err
}

if version, _ := strconv.Atoi(apiVersion); version >= 19 {
return tokenResp.Token, nil
} else if tokenResp.Token != "" {
return tokenResp.Token, nil
} else if tokenResp.ID != "" {
return tokenResp.ID, nil
}

return tokenResp.Token, nil

}
27 changes: 27 additions & 0 deletions rundeck/token_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package rundeck

import (
"os"
"testing"
)

func TestAccToken(t *testing.T) {
testAccPreCheck(t)

username := os.Getenv("RUNDECK_AUTH_USERNAME")
password := os.Getenv("RUNDECK_AUTH_PASSWORD")
apiVersion := os.Getenv("RUNDECK_API_VERSION")
if apiVersion == "" {
apiVersion = "14"
}
url := os.Getenv("RUNDECK_URL")

if username != "" && password != "" {
_, err := _getToken(url, apiVersion, username, password)
if err != nil {
t.Fatalf("failed to get a token: %s", err)
}
} else {
t.Logf("Can not run TestAccToken test as there is no username and password defined")
}
}
12 changes: 10 additions & 2 deletions website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@ The provider configuration block accepts the following arguments:
minium supported version. May alternatively be set via the ``RUNDECK_API_VERSION``
environment variable.

* ``auth_token`` - (Required) The API auth token to use when making requests. May alternatively
be set via the ``RUNDECK_AUTH_TOKEN`` environment variable.
* ``auth_token`` - The API auth token to use when making requests. May alternatively
be set via the ``RUNDECK_AUTH_TOKEN`` environment variable. (RECOMMENDED)

**OR**

* ``auth_username`` - Local Login User Name.
* ``auth_password`` - Local Login Passwrod.

> Note: Username and Password auth will not work with SSO configured systems. It relies on local Rundeck accounts. Please be sensitive to keeping passwords in your plan files!

Use the navigation to the left to read about the available resources.

Expand Down

0 comments on commit e52133f

Please sign in to comment.