Skip to content

Commit

Permalink
env0_ssh_key resource and data source
Browse files Browse the repository at this point in the history
  • Loading branch information
shlomimatichin committed Mar 16, 2021
1 parent 655214c commit e03702d
Show file tree
Hide file tree
Showing 15 changed files with 384 additions and 51 deletions.
2 changes: 1 addition & 1 deletion env0apiclient/httpverbs.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (self *ApiClient) do(req *http.Request) ([]byte, error) {
if resp.StatusCode == 204 {
return nil, nil
}
if resp.StatusCode != 200 {
if resp.StatusCode != 200 && resp.StatusCode != 201 {
return nil, errors.New(resp.Status + ": " + string(body))
}

Expand Down
85 changes: 54 additions & 31 deletions env0apiclient/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,39 +84,62 @@ const (
TemplateTypeTerragrunt TemplateType = "terragrunt"
)

type TemplateSshKey struct {
Id string `json:"id"`
Name string `json:"name"`
}

type TemplateCreatePayload struct {
Retry *TemplateRetry `json:"retry,omitempty"`
SshKeys []string `json:"sshKeys,omitempty"`
Type TemplateType `json:"type"`
Description string `json:"description,omitempty"`
Name string `json:"name"`
Repository string `json:"repository"`
Path string `json:"path,omitempty"`
IsGitLab bool `json:"isGitLab"`
TokenName string `json:"tokenName"`
TokenId string `json:"tokenId"`
GithubInstallationId int `json:"githubInstallationId"`
Revision string `json:"revision"`
ProjectIds []string `json:"projectIds,omitempty"`
OrganizationId string `json:"organizationId"`
Retry *TemplateRetry `json:"retry,omitempty"`
SshKeys []TemplateSshKey `json:"sshKeys,omitempty"`
Type TemplateType `json:"type"`
Description string `json:"description,omitempty"`
Name string `json:"name"`
Repository string `json:"repository"`
Path string `json:"path,omitempty"`
IsGitLab bool `json:"isGitLab"`
TokenName string `json:"tokenName"`
TokenId string `json:"tokenId"`
GithubInstallationId int `json:"githubInstallationId"`
Revision string `json:"revision"`
ProjectIds []string `json:"projectIds,omitempty"`
OrganizationId string `json:"organizationId"`
}

type Template struct {
Author User `json:"author"`
AuthorId string `json:"authorId"`
CreatedAt string `json:"createdAt"`
Href string `json:"href"`
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
OrganizationId string `json:"organizationId"`
Path string `json:"path"`
Revision string `json:"revision"`
ProjectId string `json:"projectId"`
ProjectIds []string `json:"projectIds"`
Repository string `json:"repository"`
Retry TemplateRetry `json:"retry"`
SshKeys []string `json:"sshKeys"`
Type string `json:"type"`
UpdatedAt string `json:"updatedAt"`
Author User `json:"author"`
AuthorId string `json:"authorId"`
CreatedAt string `json:"createdAt"`
Href string `json:"href"`
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
OrganizationId string `json:"organizationId"`
Path string `json:"path"`
Revision string `json:"revision"`
ProjectId string `json:"projectId"`
ProjectIds []string `json:"projectIds"`
Repository string `json:"repository"`
Retry TemplateRetry `json:"retry"`
SshKeys []TemplateSshKey `json:"sshKeys"`
Type string `json:"type"`
UpdatedAt string `json:"updatedAt"`
}

type SshKey struct {
User User `json:"user"`
UserId string `json:"userId"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
OrganizationId string `json:"organizationId"`
Value string `json:"value"`
}

type SshKeyCreatePayload struct {
Name string `json:"name"`
OrganizationId string `json:"organizationId"`
Value string `json:"value"`
}
49 changes: 49 additions & 0 deletions env0apiclient/sshkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package env0apiclient

import (
"errors"
"net/url"
)

func (self *ApiClient) SshKeyCreate(payload SshKeyCreatePayload) (SshKey, error) {
if payload.Name == "" {
return SshKey{}, errors.New("Must specify ssh key name on creation")
}
if payload.Value == "" {
return SshKey{}, errors.New("Must specify ssh key value (private key in PEM format) on creation")
}
if payload.OrganizationId != "" {
return SshKey{}, errors.New("Must not specify organizationId")
}
organizationId, err := self.organizationId()
if err != nil {
return SshKey{}, nil
}
payload.OrganizationId = organizationId

var result SshKey
err = self.postJSON("/ssh-keys", payload, &result)
if err != nil {
return SshKey{}, err
}
return result, nil
}

func (self *ApiClient) SshKeyDelete(id string) error {
return self.delete("/ssh-keys/" + id)
}

func (self *ApiClient) SshKeys() ([]SshKey, error) {
organizationId, err := self.organizationId()
if err != nil {
return nil, err
}
var result []SshKey
params := url.Values{}
params.Add("organizationId", organizationId)
err = self.getJSON("/ssh-keys", params, &result)
if err != nil {
return nil, err
}
return result, err
}
10 changes: 6 additions & 4 deletions env0tfprovider/data_configuration_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ func dataConfigurationVariable() *schema.Resource {
ExactlyOneOf: []string{"name", "id"},
},
"type": {
Type: schema.TypeString,
Description: "'terraform' or 'environment'. If specified as an argument, limits searching by variable name only to variables of this type.",
Optional: true,
AtLeastOneOf: []string{"name"},
Type: schema.TypeString,
Description: "'terraform' or 'environment'. If specified as an argument, limits searching by variable name only to variables of this type.",
Optional: true,
},
"id": {
Type: schema.TypeString,
Expand Down Expand Up @@ -104,6 +103,9 @@ func dataConfigurationVariableRead(ctx context.Context, d *schema.ResourceData,
name, nameOk := d.GetOk("name")
type_ := int64(-1)
if typeString, ok := d.GetOk("type"); ok {
if !nameOk {
return diag.Errorf("Specify 'type' only when searching configuration variables by 'name' (not by 'id')")
}
switch typeString.(string) {
case "environment":
type_ = int64(env0apiclient.ConfigurationVariableTypeEnvironment)
Expand Down
73 changes: 73 additions & 0 deletions env0tfprovider/data_sshkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package env0tfprovider

import (
"context"

"github.com/env0/terraform-provider-env0/env0apiclient"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSshKey() *schema.Resource {
return &schema.Resource{
ReadContext: dataSshKeyRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "the name of the ssh key",
Optional: true,
ExactlyOneOf: []string{"name", "id"},
},
"id": {
Type: schema.TypeString,
Description: "id of the ssh key",
Optional: true,
ExactlyOneOf: []string{"name", "id"},
},
},
}
}

func dataSshKeyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
apiClient := meta.(*env0apiclient.ApiClient)

name, nameSpecified := d.GetOk("name")
var sshKey env0apiclient.SshKey
if nameSpecified {
sshKeys, err := apiClient.SshKeys()
if err != nil {
return diag.Errorf("Could not query ssh keys: %v", err)
}
for _, candidate := range sshKeys {
if candidate.Name == name {
sshKey = candidate
}
}
if sshKey.Name == "" {
return diag.Errorf("Could not find an env0 ssh key with name %s", name)
}
} else {
id, idSpecified := d.GetOk("id")
if !idSpecified {
return diag.Errorf("At lease one of 'id', 'name' must be specified")
}
sshKeys, err := apiClient.SshKeys()
if err != nil {
return diag.Errorf("Could not query ssh keys: %v", err)
}
for _, candidate := range sshKeys {
if candidate.Id == id.(string) {
sshKey = candidate
}
}
if sshKey.Name == "" {
return diag.Errorf("Could not find an env0 ssh key with id %s", id)
}
}

d.SetId(sshKey.Id)
d.Set("name", sshKey.Name)

return nil
}
16 changes: 15 additions & 1 deletion env0tfprovider/data_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ func dataTemplate() *schema.Resource {
Description: "env0_project.id for each project",
},
},
"ssh_key_names": {
Type: schema.TypeList,
Description: "which ssh keys are used for accessing git over ssh",
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
Description: "env0_ssh_key.name for each project",
},
},
"retries_on_deploy": {
Type: schema.TypeInt,
Description: "number of times to retry when deploying an environment based on this template",
Expand Down Expand Up @@ -98,7 +107,7 @@ func dataTemplateRead(ctx context.Context, d *schema.ResourceData, meta interfac
return diag.Errorf("Could not find an env0 template with name %s", name)
}
} else {
template, err = apiClient.Template(d.Id())
template, err = apiClient.Template(d.Get("id").(string))
if err != nil {
return diag.Errorf("Could not query template: %v", err)
}
Expand All @@ -111,6 +120,11 @@ func dataTemplateRead(ctx context.Context, d *schema.ResourceData, meta interfac
d.Set("revision", template.Revision)
d.Set("type", template.Type)
d.Set("project_ids", template.ProjectIds)
sshKeyNames := []string{}
for _, sshKey := range template.SshKeys {
sshKeyNames = append(sshKeyNames, sshKey.Name)
}
d.Set("ssh_key_names", sshKeyNames)
if template.Retry.OnDeploy != nil {
d.Set("retries_on_deploy", template.Retry.OnDeploy.Times)
d.Set("retry_on_deploy_only_when_matches_regex", template.Retry.OnDeploy.ErrorRegex)
Expand Down
2 changes: 2 additions & 0 deletions env0tfprovider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ func Provider() *schema.Provider {
"env0_project": dataProject(),
"env0_configuration_variable": dataConfigurationVariable(),
"env0_template": dataTemplate(),
"env0_ssh_key": dataSshKey(),
},
ResourcesMap: map[string]*schema.Resource{
"env0_project": resourceProject(),
"env0_configuration_variable": resourceConfigurationVariable(),
"env0_template": resourceTemplate(),
"env0_ssh_key": resourceSshKey(),
},
ConfigureFunc: configureProvider,
}
Expand Down
Loading

0 comments on commit e03702d

Please sign in to comment.