Merge pull request #14077 from hashicorp/triton-allow-insecure
provider/triton: Add `insecure_skip_tls_verify`
This commit is contained in:
commit
ba52f8045f
|
@ -42,6 +42,12 @@ func Provider() terraform.ResourceProvider {
|
|||
Required: true,
|
||||
DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_KEY_ID", "SDC_KEY_ID"}, ""),
|
||||
},
|
||||
|
||||
"insecure_skip_tls_verify": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("TRITON_SKIP_TLS_VERIFY", ""),
|
||||
},
|
||||
},
|
||||
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
|
@ -56,10 +62,11 @@ func Provider() terraform.ResourceProvider {
|
|||
}
|
||||
|
||||
type Config struct {
|
||||
Account string
|
||||
KeyMaterial string
|
||||
KeyID string
|
||||
URL string
|
||||
Account string
|
||||
KeyMaterial string
|
||||
KeyID string
|
||||
URL string
|
||||
InsecureSkipTLSVerify bool
|
||||
}
|
||||
|
||||
func (c Config) validate() error {
|
||||
|
@ -98,6 +105,10 @@ func (c Config) getTritonClient() (*triton.Client, error) {
|
|||
return nil, errwrap.Wrapf("Error Creating Triton Client: {{err}}", err)
|
||||
}
|
||||
|
||||
if c.InsecureSkipTLSVerify {
|
||||
client.InsecureSkipTLSVerify()
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
|
@ -106,6 +117,8 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
|||
Account: d.Get("account").(string),
|
||||
URL: d.Get("url").(string),
|
||||
KeyID: d.Get("key_id").(string),
|
||||
|
||||
InsecureSkipTLSVerify: d.Get("insecure_skip_tls_verify").(bool),
|
||||
}
|
||||
|
||||
if keyMaterial, ok := d.GetOk("key_material"); ok {
|
||||
|
|
|
@ -5,8 +5,9 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
)
|
||||
|
||||
type AccountsClient struct {
|
||||
|
@ -40,7 +41,8 @@ type Account struct {
|
|||
type GetAccountInput struct{}
|
||||
|
||||
func (client *AccountsClient) GetAccount(input *GetAccountInput) (*Account, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, "/my", nil)
|
||||
path := fmt.Sprintf("/%s", client.accountName)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
@ -58,17 +60,17 @@ func (client *AccountsClient) GetAccount(input *GetAccountInput) (*Account, erro
|
|||
}
|
||||
|
||||
type UpdateAccountInput struct {
|
||||
Email string `json:"email,omitempty"`
|
||||
CompanyName string `json:"companyName,omitempty"`
|
||||
FirstName string `json:"firstName,omitempty"`
|
||||
LastName string `json:"lastName,omitempty"`
|
||||
Address string `json:"address,omitempty"`
|
||||
PostalCode string `json:"postalCode,omitempty"`
|
||||
City string `json:"city,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Country string `json:"country,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
TritonCNSEnabled bool `json:"triton_cns_enabled,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
CompanyName string `json:"companyName,omitempty"`
|
||||
FirstName string `json:"firstName,omitempty"`
|
||||
LastName string `json:"lastName,omitempty"`
|
||||
Address string `json:"address,omitempty"`
|
||||
PostalCode string `json:"postalCode,omitempty"`
|
||||
City string `json:"city,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Country string `json:"country,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
TritonCNSEnabled bool `json:"triton_cns_enabled,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateAccount updates your account details with the given parameters.
|
||||
|
|
|
@ -2,6 +2,7 @@ package triton
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -45,16 +46,7 @@ func NewClient(endpoint string, accountName string, signers ...authentication.Si
|
|||
}
|
||||
|
||||
httpClient := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
DisableKeepAlives: true,
|
||||
MaxIdleConnsPerHost: -1,
|
||||
},
|
||||
Transport: httpTransport(false),
|
||||
CheckRedirect: doNotFollowRedirects,
|
||||
}
|
||||
|
||||
|
@ -75,6 +67,34 @@ func NewClient(endpoint string, accountName string, signers ...authentication.Si
|
|||
}, nil
|
||||
}
|
||||
|
||||
// InsecureSkipTLSVerify turns off TLS verification for the client connection. This
|
||||
// allows connection to an endpoint with a certificate which was signed by a non-
|
||||
// trusted CA, such as self-signed certificates. This can be useful when connecting
|
||||
// to temporary Triton installations such as Triton Cloud-On-A-Laptop.
|
||||
func (c *Client) InsecureSkipTLSVerify() {
|
||||
if c.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.client.HTTPClient.Transport = httpTransport(true)
|
||||
}
|
||||
|
||||
func httpTransport(insecureSkipTLSVerify bool) *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
DisableKeepAlives: true,
|
||||
MaxIdleConnsPerHost: -1,
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: insecureSkipTLSVerify,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func doNotFollowRedirects(*http.Request, []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ type DataCenter struct {
|
|||
type ListDataCentersInput struct{}
|
||||
|
||||
func (client *DataCentersClient) ListDataCenters(*ListDataCentersInput) ([]*DataCenter, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, "/my/datacenters", nil)
|
||||
path := fmt.Sprintf("/%s/datacenters", client.accountName)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
@ -68,7 +69,8 @@ type GetDataCenterInput struct {
|
|||
}
|
||||
|
||||
func (client *DataCentersClient) GetDataCenter(input *GetDataCenterInput) (*DataCenter, error) {
|
||||
resp, err := client.executeRequestRaw(http.MethodGet, fmt.Sprintf("/my/datacenters/%s", input.Name), nil)
|
||||
path := fmt.Sprintf("/%s/datacenters/%s", client.accountName, input.Name)
|
||||
resp, err := client.executeRequestRaw(http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrapf("Error executing GetDatacenter request: {{err}}", err)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ type FabricVLAN struct {
|
|||
type ListFabricVLANsInput struct{}
|
||||
|
||||
func (client *FabricsClient) ListFabricVLANs(*ListFabricVLANsInput) ([]*FabricVLAN, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, "/my/fabrics/default/vlans", nil)
|
||||
path := fmt.Sprintf("/%s/fabrics/default/vlans", client.accountName)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ type FirewallRule struct {
|
|||
type ListFirewallRulesInput struct{}
|
||||
|
||||
func (client *FirewallClient) ListFirewallRules(*ListFirewallRulesInput) ([]*FirewallRule, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, "/my/fwrules", nil)
|
||||
path := fmt.Sprintf("/%s/fwrules", client.accountName)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
@ -194,7 +195,8 @@ type ListMachineFirewallRulesInput struct {
|
|||
}
|
||||
|
||||
func (client *FirewallClient) ListMachineFirewallRules(input *ListMachineFirewallRulesInput) ([]*FirewallRule, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, fmt.Sprintf("/my/machines/%s/firewallrules", input.MachineID), nil)
|
||||
path := fmt.Sprintf("/%s/machines/%s/firewallrules", client.accountName, input.MachineID)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
|
|
@ -49,7 +49,8 @@ type Image struct {
|
|||
type ListImagesInput struct{}
|
||||
|
||||
func (client *ImagesClient) ListImages(*ListImagesInput) ([]*Image, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, "/my/images", nil)
|
||||
path := fmt.Sprintf("/%s/images", client.accountName)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
@ -148,7 +149,7 @@ type CreateImageFromMachineInput struct {
|
|||
HomePage string `json:"homepage,omitempty"`
|
||||
EULA string `json:"eula,omitempty"`
|
||||
ACL []string `json:"acl,omitempty"`
|
||||
tags map[string]string `json:"tags,omitempty"`
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
func (client *ImagesClient) CreateImageFromMachine(input *CreateImageFromMachineInput) (*Image, error) {
|
||||
|
@ -178,7 +179,7 @@ type UpdateImageInput struct {
|
|||
HomePage string `json:"homepage,omitempty"`
|
||||
EULA string `json:"eula,omitempty"`
|
||||
ACL []string `json:"acl,omitempty"`
|
||||
tags map[string]string `json:"tags,omitempty"`
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
func (client *ImagesClient) UpdateImage(input *UpdateImageInput) (*Image, error) {
|
||||
|
|
|
@ -35,7 +35,8 @@ type ListKeysInput struct{}
|
|||
// ListKeys lists all public keys we have on record for the specified
|
||||
// account.
|
||||
func (client *KeysClient) ListKeys(*ListKeysInput) ([]*Key, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, "/my/keys", nil)
|
||||
path := fmt.Sprintf("/%s/keys")
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ func (client *MachinesClient) GetMachine(input *GetMachineInput) (*Machine, erro
|
|||
if response != nil {
|
||||
defer response.Body.Close()
|
||||
}
|
||||
if response.StatusCode == http.StatusNotFound {
|
||||
if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone {
|
||||
return nil, &TritonError{
|
||||
Code: "ResourceNotFound",
|
||||
}
|
||||
|
@ -219,7 +219,8 @@ func (input *CreateMachineInput) toAPI() map[string]interface{} {
|
|||
}
|
||||
|
||||
func (client *MachinesClient) CreateMachine(input *CreateMachineInput) (*Machine, error) {
|
||||
respReader, err := client.executeRequest(http.MethodPost, "/my/machines", input.toAPI())
|
||||
path := fmt.Sprintf("/%s/machines", client.accountName)
|
||||
respReader, err := client.executeRequest(http.MethodPost, path, input.toAPI())
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
@ -501,7 +502,8 @@ type ListNICsInput struct {
|
|||
}
|
||||
|
||||
func (client *MachinesClient) ListNICs(input *ListNICsInput) ([]*NIC, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, fmt.Sprintf("/my/machines/%s/nics", input.MachineID), nil)
|
||||
path := fmt.Sprintf("/%s/machines/%s/nics", client.accountName, input.MachineID)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
@ -560,6 +562,48 @@ func (client *MachinesClient) RemoveNIC(input *RemoveNICInput) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type StopMachineInput struct {
|
||||
MachineID string
|
||||
}
|
||||
|
||||
func (client *MachinesClient) StopMachine(input *StopMachineInput) error {
|
||||
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.MachineID)
|
||||
|
||||
params := &url.Values{}
|
||||
params.Set("action", "stop")
|
||||
|
||||
respReader, err := client.executeRequestURIParams(http.MethodPost, path, nil, params)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error executing StopMachine request: {{err}}", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type StartMachineInput struct {
|
||||
MachineID string
|
||||
}
|
||||
|
||||
func (client *MachinesClient) StartMachine(input *StartMachineInput) error {
|
||||
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.MachineID)
|
||||
|
||||
params := &url.Values{}
|
||||
params.Set("action", "start")
|
||||
|
||||
respReader, err := client.executeRequestURIParams(http.MethodPost, path, nil, params)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error executing StartMachine request: {{err}}", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var reservedMachineCNSTags = map[string]struct{}{
|
||||
machineCNSTagDisable: {},
|
||||
machineCNSTagReversePTR: {},
|
||||
|
|
|
@ -36,7 +36,8 @@ type Network struct {
|
|||
type ListNetworksInput struct{}
|
||||
|
||||
func (client *NetworksClient) ListNetworks(*ListNetworksInput) ([]*Network, error) {
|
||||
respReader, err := client.executeRequest(http.MethodGet, "/my/networks", nil)
|
||||
path := fmt.Sprintf("/%s/networks", client.accountName)
|
||||
respReader, err := client.executeRequest(http.MethodGet, path, nil)
|
||||
if respReader != nil {
|
||||
defer respReader.Close()
|
||||
}
|
||||
|
|
|
@ -2341,16 +2341,16 @@
|
|||
"revisionTime": "2016-06-16T18:50:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "2HimxaJVVp2QDVQ0570L71Zd5s4=",
|
||||
"checksumSHA1": "XsjyaC6eTHUy/n0iuR46TZcgAK8=",
|
||||
"path": "github.com/joyent/triton-go",
|
||||
"revision": "5db9e2b6a4c1f7ffd2a7e7aa625f42dba956608c",
|
||||
"revisionTime": "2017-04-12T23:23:58Z"
|
||||
"revision": "c73729fd38522591909a371c8180ca7090a59ab9",
|
||||
"revisionTime": "2017-04-28T18:47:44Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "QzUqkCSn/ZHyIK346xb9V6EBw9U=",
|
||||
"path": "github.com/joyent/triton-go/authentication",
|
||||
"revision": "66b31a94af28a65e902423879a2820ea34b773fb",
|
||||
"revisionTime": "2017-03-31T18:12:29Z"
|
||||
"revision": "c73729fd38522591909a371c8180ca7090a59ab9",
|
||||
"revisionTime": "2017-04-28T18:47:44Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "YhQcOsGx8r2S/jkJ0Qt4cZ5BLCU=",
|
||||
|
|
|
@ -33,3 +33,4 @@ The following arguments are supported in the `provider` block:
|
|||
* `key_material` - (Optional) This is the private key of an SSH key associated with the Triton account to be used. If this is not set, the private key corresponding to the fingerprint in `key_id` must be available via an SSH Agent.
|
||||
* `key_id` - (Required) This is the fingerprint of the public key matching the key specified in `key_path`. It can be obtained via the command `ssh-keygen -l -E md5 -f /path/to/key`
|
||||
* `url` - (Optional) This is the URL to the Triton API endpoint. It is required if using a private installation of Triton. The default is to use the Joyent public cloud us-west-1 endpoint. Valid public cloud endpoints include: `us-east-1`, `us-east-2`, `us-east-3`, `us-sw-1`, `us-west-1`, `eu-ams-1`
|
||||
* `insecure_skip_tls_verify` (Optional - defaults to false) This allows skipping TLS verification of the Triton endpoint. It is useful when connecting to a temporary Triton installation such as Cloud-On-A-Laptop which does not generally use a certificate signed by a trusted root CA.
|
||||
|
|
Loading…
Reference in New Issue