github.com/uchennaokeke444/nomad@v0.11.8/e2e/consulacls/manage.go (about)

     1  package consulacls
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/nomad/e2e/framework/provisioning"
    11  	"github.com/pkg/errors"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  // DefaultTFStateFile is the location of the TF state file, as created for the
    16  // e2e test framework. This file is used to extract the TF serial number, which
    17  // is used to determine whether the consul bootstrap process is necessary or has
    18  // already taken place.
    19  const DefaultTFStateFile = "terraform/terraform.tfstate"
    20  
    21  // A Manager is used to manipulate whether Consul ACLs are enabled or disabled.
    22  // Only works with TF provisioned clusters.
    23  type Manager interface {
    24  	// Enable Consul ACLs in the Consul cluster. The Consul ACL master token
    25  	// associated with the Consul cluster is returned.
    26  	//
    27  	// A complete bootstrap process will take place if necessary.
    28  	//
    29  	// Once enabled, Consul ACLs can be disabled with Disable.
    30  	Enable(t *testing.T) string
    31  
    32  	// Disable Consul ACLs in the Consul Cluster.
    33  	//
    34  	// Once disabled, Consul ACLs can be re-enabled with Enable.
    35  	Disable(t *testing.T)
    36  }
    37  
    38  type tfManager struct {
    39  	serial int
    40  }
    41  
    42  func New(tfStateFile string) (*tfManager, error) {
    43  	serial, err := extractSerial(tfStateFile)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	return &tfManager{
    48  		serial: serial,
    49  	}, nil
    50  }
    51  
    52  func (m *tfManager) Enable(t *testing.T) string {
    53  	// Create the local script runner that will be used to run the ACL management
    54  	// script, this time with the "enable" sub-command.
    55  	var runner provisioning.LinuxRunner
    56  	err := runner.Open(t)
    57  	require.NoError(t, err)
    58  
    59  	// Run the consul ACL bootstrap script, which will store the master token
    60  	// in the deterministic path based on the TF state serial number. If the
    61  	// bootstrap process had already taken place, ACLs will be activated but
    62  	// without going through the bootstrap process again, re-using the already
    63  	// existing Consul ACL master token.
    64  	err = runner.Run(strings.Join([]string{
    65  		"consulacls/consul-acls-manage.sh", "enable",
    66  	}, " "))
    67  	require.NoError(t, err)
    68  
    69  	// Read the Consul ACL master token that was generated (or if the token
    70  	// already existed because the bootstrap process had already taken place,
    71  	// that one).
    72  	token, err := m.readToken()
    73  	require.NoError(t, err)
    74  	return token
    75  }
    76  
    77  type tfState struct {
    78  	Serial int `json:"serial"`
    79  }
    80  
    81  // extractSerial will parse the TF state file looking for the serial number.
    82  func extractSerial(filename string) (int, error) {
    83  	if filename == "" {
    84  		filename = DefaultTFStateFile
    85  	}
    86  	b, err := ioutil.ReadFile(filename)
    87  	if err != nil {
    88  		return 0, errors.Wrap(err, "failed to extract TF serial")
    89  	}
    90  	var state tfState
    91  	if err := json.Unmarshal(b, &state); err != nil {
    92  		return 0, errors.Wrap(err, "failed to extract TF serial")
    93  	}
    94  	return state.Serial, nil
    95  }
    96  
    97  // tokenPath returns the expected path for the Consul ACL master token generated
    98  // by the consul-acls-manage.sh bootstrap script for the current TF serial version.
    99  func (m *tfManager) tokenPath() string {
   100  	return fmt.Sprintf("/tmp/e2e-consul-bootstrap-%d.token", m.serial)
   101  }
   102  
   103  func (m *tfManager) readToken() (string, error) {
   104  	b, err := ioutil.ReadFile(m.tokenPath())
   105  	if err != nil {
   106  		return "", err
   107  	}
   108  	return strings.TrimSpace(string(b)), nil
   109  }
   110  
   111  func (m *tfManager) Disable(t *testing.T) {
   112  	// Create the local script runner that will be used to run the ACL management
   113  	// script, this time with the "disable" sub-command.
   114  	var runner provisioning.LinuxRunner
   115  	err := runner.Open(t)
   116  	require.NoError(t, err)
   117  
   118  	// Run the consul ACL bootstrap script, which will modify the Consul Server
   119  	// ACL policies to disable ACLs, and then restart those agents.
   120  	err = runner.Run(strings.Join([]string{
   121  		"consulacls/consul-acls-manage.sh", "disable",
   122  	}, " "))
   123  	require.NoError(t, err)
   124  }