Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nomad/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ func Provider() *schema.Provider {
ResourcesMap: map[string]*schema.Resource{
"nomad_acl_auth_method": resourceACLAuthMethod(),
"nomad_acl_binding_rule": resourceACLBindingRule(),
"nomad_acl_bootstrap": resourceACLBootstrap(),
"nomad_acl_policy": resourceACLPolicy(),
"nomad_acl_role": resourceACLRole(),
"nomad_acl_token": resourceACLToken(),
Expand Down
136 changes: 136 additions & 0 deletions nomad/resource_acl_bootstrap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package nomad

import (
"fmt"
"log"
"strings"
"time"

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

func resourceACLBootstrap() *schema.Resource {
return &schema.Resource{
Create: resourceACLBootstrapCreate,
Delete: resourceACLBootstrapDelete,
Read: resourceACLBootstrapRead,
// Exists: resourceACLBootstrapExists,

Schema: map[string]*schema.Schema{
"accessor_id": {
Description: "Nomad-generated ID for this token.",
Computed: true,
Type: schema.TypeString,
},
"bootstrap_token": {
Description: "The value that grants access to Nomad.",
Computed: true,
Optional: true,
Sensitive: true,
Type: schema.TypeString,
},
"type": {
Description: "The type of token. This will always be 'management' for this resource.",
Computed: true,
Optional: true,
Type: schema.TypeString,
},
"roles": {
Description: "The roles associated with this token.",
Computed: true,
Optional: true,
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"global": {
Description: "Whether this token is global.",
Computed: true,
Optional: true,
Type: schema.TypeBool,
},
"create_time": {
Description: "The time this token was created in RFC3339 formate",
Computed: true,
Optional: true,
Type: schema.TypeString,
},
},
}
}

func resourceACLBootstrapCreate(d *schema.ResourceData, meta interface{}) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only support recent versions of Go, so any place we have interface{} we can use any now:

Suggested change
func resourceACLBootstrapCreate(d *schema.ResourceData, meta interface{}) error {
func resourceACLBootstrapCreate(d *schema.ResourceData, meta any) error {

providerConfig := meta.(ProviderConfig)
client := providerConfig.client

token := api.BootstrapRequest{}
if v, ok := d.GetOk("bootstrap_token"); ok {
token.BootstrapSecret = v.(string)
}
// create our token
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can leave comments like this out, especially given the log following right behind it.

Suggested change
// create our token

log.Println("[DEBUG] Creating ACL Bootstrap token with %v", token.BootstrapSecret)

Check failure on line 76 in nomad/resource_acl_bootstrap.go

View workflow job for this annotation

GitHub Actions / test

log.Println call has possible Printf formatting directive %v
resp, _, err := client.ACLTokens().BootstrapOpts(token.BootstrapSecret, nil)
if err != nil {
// Check if bootstrap was already done
if strings.Contains(err.Error(), "ACL bootstrap already done") {
return fmt.Errorf("ACL bootstrap has already been performed on this cluster. Cannot bootstrap again")
}
return fmt.Errorf("error bootstrapping the cluster: %w", err)
}
log.Printf("[DEBUG] Created ACL token AccessorID %q", resp.AccessorID)
log.Printf("[DEBUG] Created ACL token %q", resp)

Check failure on line 86 in nomad/resource_acl_bootstrap.go

View workflow job for this annotation

GitHub Actions / test

log.Printf format %q has arg resp of wrong type *github.com/hashicorp/nomad/api.ACLToken
d.SetId(resp.AccessorID)
d.Set("accessor_id", resp.AccessorID)
d.Set("bootstrap_token", resp.SecretID)
d.Set("name", resp.Name)
d.Set("type", resp.Type)
d.Set("roles", resp.Roles)
d.Set("global", resp.Global)
d.Set("create_time", resp.CreateTime.Format(time.RFC3339))

return nil
}

// not implemented as a cluster bootstrap can't be reverted
func resourceACLBootstrapDelete(d *schema.ResourceData, meta interface{}) error {
return nil
}

func resourceACLBootstrapRead(d *schema.ResourceData, meta interface{}) error {
// providerConfig := meta.(ProviderConfig)
// client := providerConfig.client
// accessor := d.Id()

// log.Printf("[DEBUG] Reading ACL bootstrap token %q", accessor)
// token, _, err := client.ACLTokens().Info(accessor, nil)
// if err != nil {
// if strings.Contains(err.Error(), "404") {
// }
// return fmt.Errorf("error reading ACL token %q: %s", accessor, err.Error())
// }
// log.Printf("[DEBUG] Read ACL bootstrap token %q", accessor)
//
// d.Set("accessor_id", token.AccessorID)
// d.Set("bootstrap_token", token.SecretID)

return nil
}

// func resourceACLBootstrapExists(d *schema.ResourceData, meta interface{}) (bool, error) {
// providerConfig := meta.(ProviderConfig)
// client := providerConfig.client
//
// accessor := d.Id()
// log.Printf("[DEBUG] Checking if ACL token %q exists", accessor)
// _, _, err := client.ACLTokens().Info(accessor, nil)
// if err != nil {
// return true, fmt.Errorf("error checking for ACL token %q: %#v", accessor, err)
// }
//
// return true, nil
// }
91 changes: 63 additions & 28 deletions scripts/start-nomad.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,46 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

set -e
set -ex

export NOMAD_TOKEN=00000000-0000-0000-0000-000000000000
NOMAD_TOKEN=00000000-0000-0000-0000-000000000000

function bootstrap_nomad_acl() {
echo "building nomad terraform provider" 1>&2
bash -c 'make'

cat <<EOF >/tmp/nomad-bootstrap.tf
provider "nomad" {
address = "http://localhost:4646"
}
resource "nomad_acl_bootstrap" "token" {
# bootstrap_token = "${NOMAD_TOKEN}"
}
output "token" {
value = nomad_acl_bootstrap.token.bootstrap_token
sensitive = true
}
EOF

export TF_CLI_CONFIG_FILE=/tmp/.terraformrc
cat <<EOF >/tmp/.terraformrc
provider_installation {
dev_overrides {
"hashicorp/nomad" = "${GOPATH}/bin/"
}

direct {}
}
EOF

echo "Bootstrapping Nomad ACL system" 1>&2
export TF_LOG=debug
cd /tmp && terraform apply -auto-approve
terraform output -raw token | tee /tmp/nomad-token.txt 1>&2
}

if [ ! -e /tmp/nomad-test.pid ]; then
cat <<EOF > /tmp/nomad-config.hcl
cat <<EOF >/tmp/nomad-config.hcl
log_file = "/tmp/nomad.log"

plugin "docker" {
Expand All @@ -17,33 +51,34 @@ plugin "docker" {
}
EOF

sudo -Eb bash -c 'nomad agent -dev -acl-enabled \
sudo -Eb bash -c 'nomad agent -dev -acl-enabled \
-data-dir=/tmp/nomad/data \
-config=/tmp/nomad-config.hcl \
echo $! > /tmp/nomad-test.pid'

# Give some time for the process to initialize
sleep 10

retries=30
while [ $retries -ge 0 ]; do
echo $NOMAD_TOKEN | nomad acl bootstrap -
if [ $? -eq 0 ]; then
break
fi
sleep 5
retries=$(( retries - 1 ))
done

# Run hostpath CSI plugin and wait for it to be healthy.
nomad job run https://raw.githubusercontent.com/hashicorp/nomad/v1.8.0/demo/csi/hostpath/plugin.nomad 1>&2
echo "Waiting for hostpath CSI plugin to become healthy" 1>&2
retries=30
while [ $retries -ge 0 ]; do
nomad plugin status hostpath \
| grep -q "Nodes Healthy = 1" && break
sleep 2
retries=$(( retries - 1 ))
done
nomad plugin status hostpath 1>&2
# Give some time for the process to initialize
sleep 10

fi

retries=3
while [ $retries -ge 0 ]; do
if bootstrap_nomad_acl; then
break
fi
sleep 5
retries=$((retries - 1))
done

export NOMAD_TOKEN
# Run hostpath CSI plugin and wait for it to be healthy.
nomad job run https://raw.githubusercontent.com/hashicorp/nomad/v1.8.0/demo/csi/hostpath/plugin.nomad 1>&2
echo "Waiting for hostpath CSI plugin to become healthy" 1>&2
retries=30
while [ $retries -ge 0 ]; do
nomad plugin status hostpath |
grep -q "Nodes Healthy = 1" && break
sleep 2
retries=$((retries - 1))
done
nomad plugin status hostpath 1>&2
Loading