packer-cn/builder/ucloud/common/access_config.go

218 lines
5.1 KiB
Go
Raw Normal View History

2019-10-12 04:46:21 -04:00
package common
2019-06-13 03:16:49 -04:00
import (
"fmt"
2019-10-25 05:24:55 -04:00
"net/url"
2019-10-14 10:41:37 -04:00
"os"
2019-06-13 03:16:49 -04:00
"github.com/hashicorp/packer/template/interpolate"
"github.com/hashicorp/packer/version"
"github.com/ucloud/ucloud-sdk-go/services/uaccount"
2019-10-12 04:46:21 -04:00
"github.com/ucloud/ucloud-sdk-go/services/ufile"
2019-06-13 03:16:49 -04:00
"github.com/ucloud/ucloud-sdk-go/services/uhost"
"github.com/ucloud/ucloud-sdk-go/services/unet"
"github.com/ucloud/ucloud-sdk-go/services/vpc"
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
)
type AccessConfig struct {
PublicKey string `mapstructure:"public_key"`
PrivateKey string `mapstructure:"private_key"`
Region string `mapstructure:"region"`
ProjectId string `mapstructure:"project_id"`
BaseUrl string `mapstructure:"base_url"`
2019-06-13 03:16:49 -04:00
client *UCloudClient
}
func (c *AccessConfig) Client() (*UCloudClient, error) {
if c.client != nil {
return c.client, nil
}
cfg := ucloud.NewConfig()
cfg.Region = c.Region
cfg.ProjectId = c.ProjectId
if c.BaseUrl != "" {
cfg.BaseUrl = c.BaseUrl
}
2019-06-13 03:16:49 -04:00
cfg.UserAgent = fmt.Sprintf("Packer-UCloud/%s", version.FormattedVersion())
2019-10-18 02:52:20 -04:00
// set default max retry count
cfg.MaxRetries = 3
2019-06-13 03:16:49 -04:00
cred := auth.NewCredential()
cred.PublicKey = c.PublicKey
cred.PrivateKey = c.PrivateKey
c.client = &UCloudClient{}
2019-10-12 04:46:21 -04:00
c.client.UHostConn = uhost.NewClient(&cfg, &cred)
c.client.UNetConn = unet.NewClient(&cfg, &cred)
c.client.VPCConn = vpc.NewClient(&cfg, &cred)
c.client.UAccountConn = uaccount.NewClient(&cfg, &cred)
c.client.UFileConn = ufile.NewClient(&cfg, &cred)
2019-06-13 03:16:49 -04:00
return c.client, nil
}
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
if err := c.Config(); err != nil {
errs = append(errs, err)
}
if c.Region == "" {
c.Region = os.Getenv("UCLOUD_REGION")
}
if c.Region == "" {
errs = append(errs, fmt.Errorf("%q must be set", "region"))
}
2019-10-25 05:24:55 -04:00
if c.BaseUrl != "" {
if _, err := url.Parse(c.BaseUrl); err != nil {
errs = append(errs, fmt.Errorf("%q is invalid, should be an valid ucloud base_url, got %q, parse error: %s", "base_url", c.BaseUrl, err))
}
}
2019-06-13 03:16:49 -04:00
if len(errs) > 0 {
return errs
}
return nil
}
func (c *AccessConfig) Config() error {
if c.PublicKey == "" {
c.PublicKey = os.Getenv("UCLOUD_PUBLIC_KEY")
}
if c.PrivateKey == "" {
c.PrivateKey = os.Getenv("UCLOUD_PRIVATE_KEY")
}
if c.ProjectId == "" {
c.ProjectId = os.Getenv("UCLOUD_PROJECT_ID")
}
if c.PublicKey == "" || c.PrivateKey == "" || c.ProjectId == "" {
return fmt.Errorf("%q, %q, and %q must be set", "public_key", "private_key", "project_id")
}
return nil
}
2019-06-14 02:50:46 -04:00
func (c *AccessConfig) ValidateProjectId(projectId string) error {
supportedProjectIds, err := c.getSupportedProjectIds()
if err != nil {
return err
}
for _, supportedProjectId := range supportedProjectIds {
if projectId == supportedProjectId {
return nil
}
}
return fmt.Errorf("%q is invalid, should be an valid ucloud project_id, got %q", "project_id", projectId)
}
2019-06-13 03:16:49 -04:00
func (c *AccessConfig) ValidateRegion(region string) error {
supportedRegions, err := c.getSupportedRegions()
if err != nil {
return err
}
for _, supportedRegion := range supportedRegions {
if region == supportedRegion {
return nil
}
}
2019-06-14 02:50:46 -04:00
return fmt.Errorf("%q is invalid, should be an valid ucloud region, got %q", "region", region)
2019-06-13 03:16:49 -04:00
}
func (c *AccessConfig) ValidateZone(region, zone string) error {
supportedZones, err := c.getSupportedZones(region)
if err != nil {
return err
}
for _, supportedZone := range supportedZones {
if zone == supportedZone {
return nil
}
}
2019-06-14 02:50:46 -04:00
return fmt.Errorf("%q is invalid, should be an valid ucloud zone, got %q", "availability_zone", zone)
}
func (c *AccessConfig) getSupportedProjectIds() ([]string, error) {
client, err := c.Client()
2019-10-12 04:46:21 -04:00
conn := client.UAccountConn
2019-06-14 02:50:46 -04:00
if err != nil {
return nil, err
}
req := conn.NewGetProjectListRequest()
resp, err := conn.GetProjectList(req)
if err != nil {
return nil, err
}
validProjectIds := make([]string, len(resp.ProjectSet))
for _, val := range resp.ProjectSet {
2019-10-12 04:46:21 -04:00
if !IsStringIn(val.ProjectId, validProjectIds) {
2019-06-14 02:50:46 -04:00
validProjectIds = append(validProjectIds, val.ProjectId)
}
}
return validProjectIds, nil
2019-06-13 03:16:49 -04:00
}
func (c *AccessConfig) getSupportedRegions() ([]string, error) {
client, err := c.Client()
2019-10-12 04:46:21 -04:00
conn := client.UAccountConn
2019-06-13 03:16:49 -04:00
if err != nil {
return nil, err
}
req := conn.NewGetRegionRequest()
resp, err := conn.GetRegion(req)
if err != nil {
return nil, err
}
validRegions := make([]string, len(resp.Regions))
for _, val := range resp.Regions {
2019-10-12 04:46:21 -04:00
if !IsStringIn(val.Region, validRegions) {
2019-06-13 03:16:49 -04:00
validRegions = append(validRegions, val.Region)
}
}
return validRegions, nil
}
func (c *AccessConfig) getSupportedZones(region string) ([]string, error) {
client, err := c.Client()
2019-10-12 04:46:21 -04:00
conn := client.UAccountConn
2019-06-13 03:16:49 -04:00
if err != nil {
return nil, err
}
req := conn.NewGetRegionRequest()
resp, err := conn.GetRegion(req)
if err != nil {
return nil, err
}
validZones := make([]string, len(resp.Regions))
for _, val := range resp.Regions {
2019-10-12 04:46:21 -04:00
if val.Region == region && !IsStringIn(val.Zone, validZones) {
2019-06-13 03:16:49 -04:00
validZones = append(validZones, val.Zone)
}
}
return validZones, nil
}