github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/builtin/provisioners/habitat/linux_provisioner_test.go (about)

     1  package habitat
     2  
     3  import (
     4  	"github.com/hashicorp/terraform/communicator"
     5  	"github.com/hashicorp/terraform/helper/schema"
     6  	"github.com/hashicorp/terraform/terraform"
     7  	"testing"
     8  )
     9  
    10  const linuxDefaultSystemdUnitFileContents = `[Unit]
    11  Description=Habitat Supervisor
    12  
    13  [Service]
    14  ExecStart=/bin/hab sup run --peer host1 --peer 1.2.3.4 --auto-update
    15  Restart=on-failure
    16  [Install]
    17  WantedBy=default.target`
    18  
    19  const linuxCustomSystemdUnitFileContents = `[Unit]
    20  Description=Habitat Supervisor
    21  
    22  [Service]
    23  ExecStart=/bin/hab sup run --listen-ctl 192.168.0.1:8443 --listen-gossip 192.168.10.1:9443 --listen-http 192.168.20.1:8080 --peer host1 --peer host2 --peer 1.2.3.4 --peer 5.6.7.8 --peer foo.example.com
    24  Restart=on-failure
    25  Environment="HAB_SUP_GATEWAY_AUTH_TOKEN=ea7-beef"
    26  Environment="HAB_AUTH_TOKEN=dead-beef"
    27  [Install]
    28  WantedBy=default.target`
    29  
    30  func TestLinuxProvisioner_linuxInstallHabitat(t *testing.T) {
    31  	cases := map[string]struct {
    32  		Config   map[string]interface{}
    33  		Commands map[string]bool
    34  	}{
    35  		"Installation with sudo": {
    36  			Config: map[string]interface{}{
    37  				"version":     "0.79.1",
    38  				"auto_update": true,
    39  				"use_sudo":    true,
    40  			},
    41  
    42  			Commands: map[string]bool{
    43  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'curl --silent -L0 https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh > install.sh'": true,
    44  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'bash ./install.sh -v 0.79.1'":                                                                                          true,
    45  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/busybox'":                                                                                             true,
    46  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg exec core/busybox adduser -D -g \"\" hab'":                                                                     true,
    47  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'rm -f install.sh'":                                                                                                     true,
    48  			},
    49  		},
    50  		"Installation without sudo": {
    51  			Config: map[string]interface{}{
    52  				"version":     "0.79.1",
    53  				"auto_update": true,
    54  				"use_sudo":    false,
    55  			},
    56  
    57  			Commands: map[string]bool{
    58  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'curl --silent -L0 https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh > install.sh'": true,
    59  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'bash ./install.sh -v 0.79.1'":                                                                                          true,
    60  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'hab install core/busybox'":                                                                                             true,
    61  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'hab pkg exec core/busybox adduser -D -g \"\" hab'":                                                                     true,
    62  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'rm -f install.sh'":                                                                                                     true,
    63  			},
    64  		},
    65  		"Installation with Habitat license acceptance": {
    66  			Config: map[string]interface{}{
    67  				"version":        "0.81.0",
    68  				"accept_license": true,
    69  				"auto_update":    true,
    70  				"use_sudo":       true,
    71  			},
    72  
    73  			Commands: map[string]bool{
    74  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'curl --silent -L0 https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh > install.sh'": true,
    75  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'bash ./install.sh -v 0.81.0'":                                                                                          true,
    76  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/busybox'":                                                                                             true,
    77  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg exec core/busybox adduser -D -g \"\" hab'":                                                                     true,
    78  				"env HAB_LICENSE=accept sudo -E /bin/bash -c 'hab -V'":                                                                                                                                        true,
    79  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'rm -f install.sh'":                                                                                                     true,
    80  			},
    81  		},
    82  	}
    83  
    84  	o := new(terraform.MockUIOutput)
    85  	c := new(communicator.MockCommunicator)
    86  
    87  	for k, tc := range cases {
    88  		c.Commands = tc.Commands
    89  
    90  		p, err := decodeConfig(
    91  			schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
    92  		)
    93  		if err != nil {
    94  			t.Fatalf("Error: %v", err)
    95  		}
    96  
    97  		err = p.linuxInstallHabitat(o, c)
    98  		if err != nil {
    99  			t.Fatalf("Test %q failed: %v", k, err)
   100  		}
   101  	}
   102  }
   103  
   104  func TestLinuxProvisioner_linuxStartHabitat(t *testing.T) {
   105  	cases := map[string]struct {
   106  		Config   map[string]interface{}
   107  		Commands map[string]bool
   108  		Uploads  map[string]string
   109  	}{
   110  		"Start systemd Habitat with sudo": {
   111  			Config: map[string]interface{}{
   112  				"version":      "0.79.1",
   113  				"auto_update":  true,
   114  				"use_sudo":     true,
   115  				"service_name": "hab-sup",
   116  				"peer":         "--peer host1",
   117  				"peers":        []interface{}{"1.2.3.4"},
   118  			},
   119  
   120  			Commands: map[string]bool{
   121  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/hab-sup/0.79.1'":                             true,
   122  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'systemctl enable hab-sup && systemctl start hab-sup'":         true,
   123  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mv /tmp/hab-sup.service /etc/systemd/system/hab-sup.service'": true,
   124  			},
   125  
   126  			Uploads: map[string]string{
   127  				"/tmp/hab-sup.service": linuxDefaultSystemdUnitFileContents,
   128  			},
   129  		},
   130  		"Start systemd Habitat without sudo": {
   131  			Config: map[string]interface{}{
   132  				"version":      "0.79.1",
   133  				"auto_update":  true,
   134  				"use_sudo":     false,
   135  				"service_name": "hab-sup",
   136  				"peer":         "--peer host1",
   137  				"peers":        []interface{}{"1.2.3.4"},
   138  			},
   139  
   140  			Commands: map[string]bool{
   141  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'hab install core/hab-sup/0.79.1'":                     true,
   142  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true /bin/bash -c 'systemctl enable hab-sup && systemctl start hab-sup'": true,
   143  			},
   144  
   145  			Uploads: map[string]string{
   146  				"/etc/systemd/system/hab-sup.service": linuxDefaultSystemdUnitFileContents,
   147  			},
   148  		},
   149  		"Start unmanaged Habitat with sudo": {
   150  			Config: map[string]interface{}{
   151  				"version":      "0.81.0",
   152  				"license":      "accept-no-persist",
   153  				"auto_update":  true,
   154  				"use_sudo":     true,
   155  				"service_type": "unmanaged",
   156  				"peer":         "--peer host1",
   157  				"peers":        []interface{}{"1.2.3.4"},
   158  			},
   159  
   160  			Commands: map[string]bool{
   161  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab install core/hab-sup/0.81.0'":                                                                                true,
   162  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mkdir -p /hab/sup/default && chmod o+w /hab/sup/default'":                                                        true,
   163  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c '(setsid hab sup run --peer host1 --peer 1.2.3.4 --auto-update > /hab/sup/default/sup.log 2>&1 <&1 &) ; sleep 1'": true,
   164  			},
   165  
   166  			Uploads: map[string]string{
   167  				"/etc/systemd/system/hab-sup.service": linuxDefaultSystemdUnitFileContents,
   168  			},
   169  		},
   170  		"Start Habitat with custom config": {
   171  			Config: map[string]interface{}{
   172  				"version":            "0.79.1",
   173  				"auto_update":        false,
   174  				"use_sudo":           true,
   175  				"service_name":       "hab-sup",
   176  				"peer":               "--peer host1 --peer host2",
   177  				"peers":              []interface{}{"1.2.3.4", "5.6.7.8", "foo.example.com"},
   178  				"listen_ctl":         "192.168.0.1:8443",
   179  				"listen_gossip":      "192.168.10.1:9443",
   180  				"listen_http":        "192.168.20.1:8080",
   181  				"builder_auth_token": "dead-beef",
   182  				"gateway_auth_token": "ea7-beef",
   183  				"ctl_secret":         "bad-beef",
   184  			},
   185  
   186  			Commands: map[string]bool{
   187  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true HAB_AUTH_TOKEN=dead-beef sudo -E /bin/bash -c 'hab install core/hab-sup/0.79.1'":                             true,
   188  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true HAB_AUTH_TOKEN=dead-beef sudo -E /bin/bash -c 'systemctl enable hab-sup && systemctl start hab-sup'":         true,
   189  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true HAB_AUTH_TOKEN=dead-beef sudo -E /bin/bash -c 'mv /tmp/hab-sup.service /etc/systemd/system/hab-sup.service'": true,
   190  			},
   191  
   192  			Uploads: map[string]string{
   193  				"/tmp/hab-sup.service": linuxCustomSystemdUnitFileContents,
   194  			},
   195  		},
   196  	}
   197  
   198  	o := new(terraform.MockUIOutput)
   199  	c := new(communicator.MockCommunicator)
   200  
   201  	for k, tc := range cases {
   202  		c.Commands = tc.Commands
   203  		c.Uploads = tc.Uploads
   204  
   205  		p, err := decodeConfig(
   206  			schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
   207  		)
   208  		if err != nil {
   209  			t.Fatalf("Error: %v", err)
   210  		}
   211  
   212  		err = p.linuxStartHabitat(o, c)
   213  		if err != nil {
   214  			t.Fatalf("Test %q failed: %v", k, err)
   215  		}
   216  	}
   217  }
   218  
   219  func TestLinuxProvisioner_linuxUploadRingKey(t *testing.T) {
   220  	cases := map[string]struct {
   221  		Config   map[string]interface{}
   222  		Commands map[string]bool
   223  	}{
   224  		"Upload ring key": {
   225  			Config: map[string]interface{}{
   226  				"version":          "0.79.1",
   227  				"auto_update":      true,
   228  				"use_sudo":         true,
   229  				"service_name":     "hab-sup",
   230  				"peers":            []interface{}{"1.2.3.4"},
   231  				"ring_key":         "test-ring",
   232  				"ring_key_content": "dead-beef",
   233  			},
   234  
   235  			Commands: map[string]bool{
   236  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'echo -e \"dead-beef\" | hab ring key import'": true,
   237  			},
   238  		},
   239  	}
   240  
   241  	o := new(terraform.MockUIOutput)
   242  	c := new(communicator.MockCommunicator)
   243  
   244  	for k, tc := range cases {
   245  		c.Commands = tc.Commands
   246  
   247  		p, err := decodeConfig(
   248  			schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
   249  		)
   250  		if err != nil {
   251  			t.Fatalf("Error: %v", err)
   252  		}
   253  
   254  		err = p.linuxUploadRingKey(o, c)
   255  		if err != nil {
   256  			t.Fatalf("Test %q failed: %v", k, err)
   257  		}
   258  	}
   259  }
   260  
   261  func TestLinuxProvisioner_linuxStartHabitatService(t *testing.T) {
   262  	cases := map[string]struct {
   263  		Config   map[string]interface{}
   264  		Commands map[string]bool
   265  		Uploads  map[string]string
   266  	}{
   267  		"Start Habitat service with sudo": {
   268  			Config: map[string]interface{}{
   269  				"version":          "0.79.1",
   270  				"auto_update":      false,
   271  				"use_sudo":         true,
   272  				"service_name":     "hab-sup",
   273  				"peers":            []interface{}{"1.2.3.4"},
   274  				"ring_key":         "test-ring",
   275  				"ring_key_content": "dead-beef",
   276  				"service": []interface{}{
   277  					map[string]interface{}{
   278  						"name":      "core/foo",
   279  						"topology":  "standalone",
   280  						"strategy":  "none",
   281  						"channel":   "stable",
   282  						"user_toml": "[config]\nlisten = 0.0.0.0:8080",
   283  						"bind": []interface{}{
   284  							map[string]interface{}{
   285  								"alias":   "backend",
   286  								"service": "bar",
   287  								"group":   "default",
   288  							},
   289  						},
   290  					},
   291  					map[string]interface{}{
   292  						"name":      "core/bar",
   293  						"topology":  "standalone",
   294  						"strategy":  "rolling",
   295  						"channel":   "staging",
   296  						"user_toml": "[config]\nlisten = 0.0.0.0:443",
   297  					},
   298  				},
   299  			},
   300  
   301  			Commands: map[string]bool{
   302  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg install core/foo  --channel stable'":                                                                        true,
   303  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mkdir -p /hab/user/foo/config'":                                                                                     true,
   304  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mv /tmp/user-a5b83ec1b302d109f41852ae17379f75c36dff9bc598aae76b6f7c9cd425fd76.toml /hab/user/foo/config/user.toml'": true,
   305  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab svc load core/foo  --topology standalone --strategy none --channel stable --bind backend:bar.default'":          true,
   306  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab pkg install core/bar  --channel staging'":                                                                       true,
   307  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mkdir -p /hab/user/bar/config'":                                                                                     true,
   308  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'mv /tmp/user-6466ae3283ae1bd4737b00367bc676c6465b25682169ea5f7da222f3f078a5bf.toml /hab/user/bar/config/user.toml'": true,
   309  				"env HAB_NONINTERACTIVE=true HAB_NOCOLORING=true sudo -E /bin/bash -c 'hab svc load core/bar  --topology standalone --strategy rolling --channel staging'":                                 true,
   310  			},
   311  
   312  			Uploads: map[string]string{
   313  				"/tmp/user-a5b83ec1b302d109f41852ae17379f75c36dff9bc598aae76b6f7c9cd425fd76.toml": "[config]\nlisten = 0.0.0.0:8080",
   314  				"/tmp/user-6466ae3283ae1bd4737b00367bc676c6465b25682169ea5f7da222f3f078a5bf.toml": "[config]\nlisten = 0.0.0.0:443",
   315  			},
   316  		},
   317  	}
   318  
   319  	o := new(terraform.MockUIOutput)
   320  	c := new(communicator.MockCommunicator)
   321  
   322  	for k, tc := range cases {
   323  		c.Commands = tc.Commands
   324  		c.Uploads = tc.Uploads
   325  
   326  		p, err := decodeConfig(
   327  			schema.TestResourceDataRaw(t, Provisioner().(*schema.Provisioner).Schema, tc.Config),
   328  		)
   329  		if err != nil {
   330  			t.Fatalf("Error: %v", err)
   331  		}
   332  
   333  		var errs []error
   334  		for _, s := range p.Services {
   335  			err = p.linuxStartHabitatService(o, c, s)
   336  			if err != nil {
   337  				errs = append(errs, err)
   338  			}
   339  		}
   340  
   341  		if len(errs) > 0 {
   342  			for _, e := range errs {
   343  				t.Logf("Test %q failed: %v", k, e)
   344  				t.Fail()
   345  			}
   346  		}
   347  	}
   348  }