server.garden privileged automation agent (mirror of https://git.sequentialread.com/forest/rootsystem)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

113 lines
3.4 KiB

package automation
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
errors "git.sequentialread.com/forest/pkg-errors"
"git.sequentialread.com/forest/rootsystem/configuration"
)
type digialOceanSSHKeysResponse struct {
SSHKeys []digitalOceanSSHKey `json:"ssh_keys"`
}
type digitalOceanSSHKey struct {
Id int `json:"id"`
Fingerprint string `json:"fingerprint"`
PublicKey string `json:"public_key"`
Pame string `json:"name"`
}
func handleDigitalOceanSSHKeyAlreadyExists(
config *configuration.Configuration,
workingDirectory string,
terraformDirectory string,
tfShow *TerraformShow,
) (bool, error) {
var digitaloceanCredential *configuration.Credential = nil
for _, cred := range config.Credentials {
if cred.Type == configuration.DIGITALOCEAN {
digitaloceanCredential = &cred
break
}
}
createSSHKeys := filterResourceChanges(
tfShow,
ResourceChangeFilter{ResourceType: "digitalocean_ssh_key", Action: "create", NotAction: "delete"},
)
if digitaloceanCredential == nil || len(createSSHKeys) == 0 {
return false, nil
}
// createAnySSHKeys
// for _, module := range tfShow.PlannedValues.RootModule.ChildModules {
// for _, resource := range module.Resources {
// if resource.Type == "digitalocean_ssh_key" {
// }
// }
// }
// Get the ssh public keys from digital ocean API
httpClient := http.Client{}
request, err := http.NewRequest("GET", fmt.Sprintf("%s%s", configuration.DIGITALOCEAN_API_URL, "/v2/account/keys"), nil)
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", digitaloceanCredential.Password))
response, err := httpClient.Do(request)
if err != nil {
return false, err
}
if response.StatusCode != 200 {
return false, fmt.Errorf("HTTP %d when calling /v2/account/keys on digitalocean API", response.StatusCode)
}
bytes, err := ioutil.ReadAll(response.Body)
if err != nil {
return false, errors.Wrap(err, "HTTP read error when calling /v2/account/keys on digitalocean API")
}
var responseObject digialOceanSSHKeysResponse
err = json.Unmarshal(bytes, &responseObject)
if err != nil {
return false, errors.Wrap(err, "JSON parse error when calling /v2/account/keys on digitalocean API")
}
digitalOceanIdByKeyContent := map[string]int{}
for _, sshKey := range responseObject.SSHKeys {
digitalOceanIdByKeyContent[strings.TrimSpace(sshKey.PublicKey)] = sshKey.Id
}
importedAnySSHKeys := false
// for each local SSH key which tf plans to create, check if it already exists in DO
for _, resource := range createSSHKeys {
sshKeyContent, hasContent := getStringValue(resource, "public_key")
if !hasContent {
return false, fmt.Errorf("digitalocean_ssh_key %s (from terraform planned_values) is missing string value \"public_key\" ", resource.Address)
}
digitalOceanId, has := digitalOceanIdByKeyContent[strings.TrimSpace(sshKeyContent)]
if has {
fmt.Println("---------------------------------------")
fmt.Printf(
"Terraform plans to add the local ssh public key %s to digitalocean, but digitalocean already has that key \n",
resource.Values["name"],
)
exitCode := removeAndImportResource(terraformDirectory, resource.Address, strconv.Itoa(digitalOceanId))
if exitCode != 0 {
return false, errors.New("terraform import returned a non-zero exit code")
}
importedAnySSHKeys = true
fmt.Println("---------------------------------------")
}
}
return importedAnySSHKeys, nil
}