From 52d0d0f7c07a6d3399cb8115a76414590de298d7 Mon Sep 17 00:00:00 2001 From: Yusuke Kuoka Date: Sun, 24 Jan 2021 16:22:39 +0900 Subject: [PATCH] Extract more parts into the sdk --- pkg/courier/courier_r53_ops.go | 8 +- pkg/courier/read_alb.go | 8 +- pkg/provider/configure.go | 3 +- pkg/provider/provider.go | 3 +- pkg/resource/cluster/aws_session.go | 1 - pkg/resource/cluster/binary_eksctl.go | 106 +---------------- pkg/resource/cluster/cluster_create.go | 9 +- pkg/resource/cluster/cluster_read.go | 43 +------ pkg/resource/cluster/command_eksctl.go | 5 +- pkg/resource/cluster/resource.go | 4 +- pkg/resource/cluster/resource_read.go | 4 +- pkg/resource/courier/resource_courier_alb.go | 7 +- .../resource_courier_route53_record.go | 7 +- .../iamserviceaccount/iamserviceaccount.go | 4 +- pkg/sdk/api/readwrite.go | 9 ++ pkg/sdk/assume_role_config.go | 76 ------------- pkg/sdk/aws_session.go | 35 ------ pkg/sdk/job.go | 43 +++++++ pkg/sdk/prepare_exec.go | 107 ++++++++++++++++++ pkg/sdk/tfsdk/assume_role_config_get.go | 78 +++++++++++++ pkg/sdk/tfsdk/aws_region_profile_get.go | 19 ++++ pkg/sdk/tfsdk/aws_session_get.go | 25 ++++ pkg/sdk/{const.go => tfsdk/constants.go} | 2 +- pkg/sdk/tfsdk/diff_read_write.go | 27 +++++ 24 files changed, 347 insertions(+), 286 deletions(-) create mode 100644 pkg/sdk/api/readwrite.go create mode 100644 pkg/sdk/job.go create mode 100644 pkg/sdk/prepare_exec.go create mode 100644 pkg/sdk/tfsdk/assume_role_config_get.go create mode 100644 pkg/sdk/tfsdk/aws_region_profile_get.go create mode 100644 pkg/sdk/tfsdk/aws_session_get.go rename pkg/sdk/{const.go => tfsdk/constants.go} (87%) create mode 100644 pkg/sdk/tfsdk/diff_read_write.go diff --git a/pkg/courier/courier_r53_ops.go b/pkg/courier/courier_r53_ops.go index 5514750..b253448 100644 --- a/pkg/courier/courier_r53_ops.go +++ b/pkg/courier/courier_r53_ops.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" "golang.org/x/sync/errgroup" "golang.org/x/xerrors" "log" @@ -16,7 +16,7 @@ import ( func CreateOrUpdateCourierRoute53Record(d api.Getter, mSchema *MetricSchema) error { ctx := context.Background() - sess := sdk.AWSSessionFromResourceData(d) + sess := tfsdk.AWSSessionFromResourceData(d) if v := d.Get("address"); v != nil { sess.Config.Endpoint = aws.String(v.(string)) @@ -33,7 +33,7 @@ func CreateOrUpdateCourierRoute53Record(d api.Getter, mSchema *MetricSchema) err return xerrors.Errorf("calling route53.GetHostedZone: %w", err) } - region, profile := sdk.GetAWSRegionAndProfile(d) + region, profile := tfsdk.GetAWSRegionAndProfile(d) recordName := d.Get("name").(string) @@ -74,7 +74,7 @@ func CreateOrUpdateCourierRoute53Record(d api.Getter, mSchema *MetricSchema) err stepWeight = v.(int) } - assumeRoleConfig := sdk.GetAssumeRoleConfig(d) + assumeRoleConfig := tfsdk.GetAssumeRoleConfig(d) r := &Route53RecordSetRouter{ Service: svc, diff --git a/pkg/courier/read_alb.go b/pkg/courier/read_alb.go index 744863b..e672e49 100644 --- a/pkg/courier/read_alb.go +++ b/pkg/courier/read_alb.go @@ -2,8 +2,8 @@ package courier import ( "fmt" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" "golang.org/x/xerrors" "strconv" "time" @@ -28,14 +28,14 @@ type ALBSchema struct { } func ReadCourierALB(d api.Lister, schema *ALBSchema, metricSchema *MetricSchema) (*CourierALB, error) { - region, profile := sdk.GetAWSRegionAndProfile(d) + region, profile := tfsdk.GetAWSRegionAndProfile(d) - sess := sdk.AWSSessionFromResourceData(d) + sess := tfsdk.AWSSessionFromResourceData(d) conf := CourierALB{ Region: region, Profile: profile, - AssumeRoleConfig: sdk.GetAssumeRoleConfig(d), + AssumeRoleConfig: tfsdk.GetAssumeRoleConfig(d), Session: sess, } diff --git a/pkg/provider/configure.go b/pkg/provider/configure.go index d631874..bcb662e 100644 --- a/pkg/provider/configure.go +++ b/pkg/provider/configure.go @@ -3,7 +3,6 @@ package provider import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" ) @@ -13,7 +12,7 @@ type ProviderInstance struct { func providerConfigure() func(*schema.ResourceData) (interface{}, error) { return func(d *schema.ResourceData) (interface{}, error) { - s := sdk.AWSSessionFromResourceData(&tfsdk.Resource{d}) + s := tfsdk.AWSSessionFromResourceData(&tfsdk.Resource{d}) return &ProviderInstance{ AWSSession: s, diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index dc6f194..e6008a1 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -6,7 +6,6 @@ import ( "github.com/mumoshu/terraform-provider-eksctl/pkg/resource/cluster" "github.com/mumoshu/terraform-provider-eksctl/pkg/resource/courier" "github.com/mumoshu/terraform-provider-eksctl/pkg/resource/iamserviceaccount" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" ) @@ -16,7 +15,7 @@ func Provider() terraform.ResourceProvider { // The actual provider return &schema.Provider{ Schema: map[string]*schema.Schema{ - sdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), + tfsdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), }, ResourcesMap: map[string]*schema.Resource{ "eksctl_cluster": cluster.ResourceCluster(), diff --git a/pkg/resource/cluster/aws_session.go b/pkg/resource/cluster/aws_session.go index d62a9b0..f80b26f 100644 --- a/pkg/resource/cluster/aws_session.go +++ b/pkg/resource/cluster/aws_session.go @@ -10,4 +10,3 @@ func AWSSessionFromCluster(cluster *Cluster) *session.Session { return sess } - diff --git a/pkg/resource/cluster/binary_eksctl.go b/pkg/resource/cluster/binary_eksctl.go index 55af163..5461210 100644 --- a/pkg/resource/cluster/binary_eksctl.go +++ b/pkg/resource/cluster/binary_eksctl.go @@ -1,111 +1,9 @@ package cluster import ( - "bufio" - "fmt" - "github.com/mumoshu/shoal" - "golang.org/x/sync/errgroup" - "golang.org/x/xerrors" - "io" - "log" - "path/filepath" - "sync" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" ) -var prepareEksctlMu sync.Mutex - func prepareEksctlBinary(cluster *Cluster) (*string, error) { - return prepareEksctlBinaryInternal(cluster.EksctlBin, cluster.EksctlVersion) -} - -func prepareEksctlBinaryInternal(eksctlBin, eksctlVersion string) (*string, error) { - log.Print("Preparing eksctl binary") - - conf := shoal.Config{ - Git: shoal.Git{ - Provider: "go-git", - }, - } - - rig := "https://github.com/fishworks/fish-food" - - installEksctl := eksctlVersion != "" - - if installEksctl { - log.Printf("Installing eksctl %s", eksctlVersion) - - conf.Dependencies = append(conf.Dependencies, - shoal.Dependency{ - Rig: rig, - Food: "eksctl", - Version: eksctlVersion, - }, - ) - } - - log.Print("Started taking exclusive lock on shoal") - - prepareEksctlMu.Lock() - defer prepareEksctlMu.Unlock() - - log.Print("Took exclusive lock on shoal") - - logReader, logWriter := io.Pipe() - - s, err := shoal.New(shoal.LogOutput(logWriter)) - if err != nil { - return nil, err - } - - log.Print("Shoal instance created") - - if len(conf.Dependencies) > 0 { - eg := errgroup.Group{} - - scanner := bufio.NewScanner(logReader) - - eg.Go(func() error { - for scanner.Scan() { - log.Printf("shoal] %s", scanner.Text()) - } - - return nil - }) - - if err := s.Init(); err != nil { - return nil, fmt.Errorf("initializing shoal: %w", err) - } - - log.Print("Shoal initialized") - - if err := s.InitGitProvider(conf); err != nil { - return nil, fmt.Errorf("initializing shoal git provider: %w", err) - } - - log.Print("Shoal's Git provider initialized") - - eg.Go(func() error { - defer logWriter.Close() - - if err := s.Sync(conf); err != nil { - return xerrors.Errorf("running shoal-sync: %w", err) - } - - return nil - }) - - if err := eg.Wait(); err != nil { - return nil, xerrors.Errorf("calling shoal: %w", err) - } - - log.Println("Shoal sync finished") - } - - binPath := s.BinPath() - - if eksctlVersion != "" { - eksctlBin = filepath.Join(binPath, "eksctl") - } - - return &eksctlBin, nil + return sdk.PrepareExecutable(cluster.EksctlBin, "eksctl", cluster.EksctlVersion) } diff --git a/pkg/resource/cluster/cluster_create.go b/pkg/resource/cluster/cluster_create.go index 5a0bb54..f8fe418 100644 --- a/pkg/resource/cluster/cluster_create.go +++ b/pkg/resource/cluster/cluster_create.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" "io/ioutil" "log" "os" @@ -13,7 +14,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - ) +) func (m *Manager) createCluster(d *schema.ResourceData) (*ClusterSet, error) { id := newClusterID() @@ -67,7 +68,7 @@ func (m *Manager) createCluster(d *schema.ResourceData) (*ClusterSet, error) { return set, nil } -func (m *Manager) doPlanKubeconfig(d *DiffReadWrite) error { +func (m *Manager) doPlanKubeconfig(d *tfsdk.DiffReadWrite) error { var path string if v := d.Get(KeyKubeconfigPath); v != nil { @@ -81,7 +82,7 @@ func (m *Manager) doPlanKubeconfig(d *DiffReadWrite) error { return nil } -func doWriteKubeconfig(ctx *sdk.Context, d ReadWrite, clusterName, region string) error { +func doWriteKubeconfig(ctx *sdk.Context, d api.ReadWrite, clusterName, region string) error { var path string if v := d.Get(KeyKubeconfigPath); v != nil { @@ -141,7 +142,7 @@ func doWriteKubeconfig(ctx *sdk.Context, d ReadWrite, clusterName, region string return nil } -func createIAMIdentityMapping(ctx *sdk.Context, d ReadWrite, cluster *Cluster) error { +func createIAMIdentityMapping(ctx *sdk.Context, d api.ReadWrite, cluster *Cluster) error { iams, err := runGetIAMIdentityMapping(ctx, d, cluster) if err != nil { return fmt.Errorf("can not get iamidentitymapping from eks cluster: %w", err) diff --git a/pkg/resource/cluster/cluster_read.go b/pkg/resource/cluster/cluster_read.go index 04800d9..b3928f8 100644 --- a/pkg/resource/cluster/cluster_read.go +++ b/pkg/resource/cluster/cluster_read.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" "golang.org/x/xerrors" "log" "os" @@ -15,39 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) -type ReadWrite interface { - api.Getter - - Id() string - - Set(string, interface{}) error -} - -type DiffReadWrite struct { - D *schema.ResourceDiff -} - -func (d *DiffReadWrite) Get(k string) interface{} { - return d.D.Get(k) -} - -func (d *DiffReadWrite) List(k string) []interface{} { - return nil -} - -func (d *DiffReadWrite) Set(k string, v interface{}) error { - return d.D.SetNew(k, v) -} - -func (d *DiffReadWrite) SetNewComputed(k string) error { - return d.D.SetNewComputed(k) -} - -func (d *DiffReadWrite) Id() string { - return d.D.Id() -} - -func (m *Manager) readCluster(d ReadWrite) (*Cluster, error) { +func (m *Manager) readCluster(d api.ReadWrite) (*Cluster, error) { cluster, err := m.readClusterInternal(d) ctx := mustNewContext(cluster) @@ -85,7 +54,7 @@ func (m *Manager) readCluster(d ReadWrite) (*Cluster, error) { func (m *Manager) readClusterInternal(d api.Resource) (*Cluster, error) { clusterNamePrefix := d.Get("name").(string) - sess := sdk.AWSSessionFromResourceData(d) + sess := tfsdk.AWSSessionFromResourceData(d) arns, err := getTargetGroupARNs(sess, clusterNamePrefix) if err != nil { @@ -110,7 +79,7 @@ func (m *Manager) readClusterInternal(d api.Resource) (*Cluster, error) { return c, err } -func (m *Manager) planCluster(d *DiffReadWrite) error { +func (m *Manager) planCluster(d *tfsdk.DiffReadWrite) error { _, err := m.readClusterInternal(d) if err != nil { return err @@ -123,7 +92,7 @@ func (m *Manager) planCluster(d *DiffReadWrite) error { return nil } -func readIAMIdentityMapping(ctx *sdk.Context, d ReadWrite, cluster *Cluster) error { +func readIAMIdentityMapping(ctx *sdk.Context, d api.ReadWrite, cluster *Cluster) error { iamWithOIDCEnabled, err := cluster.IAMWithOIDCEnabled() if err != nil { return fmt.Errorf("reading iam.withOIDC setting from cluster.yaml: %w", err) @@ -188,7 +157,7 @@ func runGetIAMIdentityMapping(ctx *sdk.Context, d api.Getter, cluster *Cluster) return iams, nil } -func loadOIDCProviderURLAndARN(d ReadWrite, cluster *Cluster) error { +func loadOIDCProviderURLAndARN(d api.ReadWrite, cluster *Cluster) error { iamWithOIDCEnabled, err := cluster.IAMWithOIDCEnabled() if err != nil { return fmt.Errorf("reading iam.withOIDC setting from cluster.yaml: %w", err) diff --git a/pkg/resource/cluster/command_eksctl.go b/pkg/resource/cluster/command_eksctl.go index 8276c3b..72f2242 100644 --- a/pkg/resource/cluster/command_eksctl.go +++ b/pkg/resource/cluster/command_eksctl.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" "os/exec" ) @@ -11,12 +12,12 @@ func newEksctlCommandFromResourceWithRegionAndProfile(resource api.Getter, args eksctlBin := resource.Get(KeyBin).(string) eksctlVersion := resource.Get(KeyEksctlVersion).(string) - bin, err := prepareEksctlBinaryInternal(eksctlBin, eksctlVersion) + bin, err := sdk.PrepareExecutable(eksctlBin, "eksctl", eksctlVersion) if err != nil { return nil, fmt.Errorf("preparing eksctl binary: %w", err) } - region, profile := sdk.GetAWSRegionAndProfile(resource) + region, profile := tfsdk.GetAWSRegionAndProfile(resource) if region != "" { args = append(args, "--region", region) diff --git a/pkg/resource/cluster/resource.go b/pkg/resource/cluster/resource.go index b2320c4..678067f 100644 --- a/pkg/resource/cluster/resource.go +++ b/pkg/resource/cluster/resource.go @@ -45,7 +45,7 @@ func ResourceCluster() *schema.Resource { } }() - if err := m.planCluster(&DiffReadWrite{D: d}); err != nil { + if err := m.planCluster(&tfsdk.DiffReadWrite{D: d}); err != nil { return fmt.Errorf("diffing cluster: %w", err) } @@ -142,7 +142,7 @@ func ResourceCluster() *schema.Resource { Optional: true, Default: "", }, - sdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), + tfsdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), KeyName: { Type: schema.TypeString, Required: true, diff --git a/pkg/resource/cluster/resource_read.go b/pkg/resource/cluster/resource_read.go index 59e03f5..d4142b5 100644 --- a/pkg/resource/cluster/resource_read.go +++ b/pkg/resource/cluster/resource_read.go @@ -2,8 +2,8 @@ package cluster import ( "fmt" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" ) func ReadCluster(d api.Getter) (*Cluster, error) { @@ -81,7 +81,7 @@ func ReadCluster(d api.Getter) (*Cluster, error) { } } - if cfg := sdk.GetAssumeRoleConfig(d); cfg != nil { + if cfg := tfsdk.GetAssumeRoleConfig(d); cfg != nil { a.AssumeRoleConfig = cfg } diff --git a/pkg/resource/courier/resource_courier_alb.go b/pkg/resource/courier/resource_courier_alb.go index 4cac912..a112d3d 100644 --- a/pkg/resource/courier/resource_courier_alb.go +++ b/pkg/resource/courier/resource_courier_alb.go @@ -5,7 +5,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/mumoshu/terraform-provider-eksctl/pkg/courier" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" "github.com/rs/xid" "golang.org/x/xerrors" @@ -130,12 +129,12 @@ func ResourceALB() *schema.Resource { return nil }, Schema: map[string]*schema.Schema{ - sdk.KeyRegion: { + tfsdk.KeyRegion: { Type: schema.TypeString, Optional: true, Default: "", }, - sdk.KeyProfile: { + tfsdk.KeyProfile: { Type: schema.TypeString, Optional: true, Default: "", @@ -145,7 +144,7 @@ func ResourceALB() *schema.Resource { Optional: true, Default: "", }, - sdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), + tfsdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), "listener_arn": { Type: schema.TypeString, Required: true, diff --git a/pkg/resource/courier/resource_courier_route53_record.go b/pkg/resource/courier/resource_courier_route53_record.go index 96a1104..962b4e3 100644 --- a/pkg/resource/courier/resource_courier_route53_record.go +++ b/pkg/resource/courier/resource_courier_route53_record.go @@ -5,7 +5,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/mumoshu/terraform-provider-eksctl/pkg/courier" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/tfsdk" "github.com/rs/xid" ) @@ -43,12 +42,12 @@ func ResourceRoute53Record() *schema.Resource { return nil }, Schema: map[string]*schema.Schema{ - sdk.KeyRegion: { + tfsdk.KeyRegion: { Type: schema.TypeString, Optional: true, Default: "", }, - sdk.KeyProfile: { + tfsdk.KeyProfile: { Type: schema.TypeString, Optional: true, Default: "", @@ -58,7 +57,7 @@ func ResourceRoute53Record() *schema.Resource { Optional: true, Default: "", }, - sdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), + tfsdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), "zone_id": { Type: schema.TypeString, Required: true, diff --git a/pkg/resource/iamserviceaccount/iamserviceaccount.go b/pkg/resource/iamserviceaccount/iamserviceaccount.go index 694704c..7186d49 100644 --- a/pkg/resource/iamserviceaccount/iamserviceaccount.go +++ b/pkg/resource/iamserviceaccount/iamserviceaccount.go @@ -102,7 +102,7 @@ func Resource() *schema.Resource { Required: true, ForceNew: true, }, - sdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), + tfsdk.KeyAssumeRole: tfsdk.SchemaAssumeRole(), sdk.KeyOutput: { Type: schema.TypeString, Computed: true, @@ -131,7 +131,7 @@ func ReadIAMServiceAccount(d *schema.ResourceData) *IAMServiceAccount { a.Cluster = d.Get(KeyCluster).(string) a.AttachPolicyARN = d.Get(KeyAttachPolicyARN).(string) a.OverrideExistingServiceAccounts = d.Get(KeyOverrideExistingServiceAccounts).(bool) - if cfg := sdk.GetAssumeRoleConfig(d); cfg != nil { + if cfg := tfsdk.GetAssumeRoleConfig(d); cfg != nil { a.AssumeRoleConfig = cfg } diff --git a/pkg/sdk/api/readwrite.go b/pkg/sdk/api/readwrite.go new file mode 100644 index 0000000..79a71a6 --- /dev/null +++ b/pkg/sdk/api/readwrite.go @@ -0,0 +1,9 @@ +package api + +type ReadWrite interface { + Getter + + Id() string + + Set(string, interface{}) error +} diff --git a/pkg/sdk/assume_role_config.go b/pkg/sdk/assume_role_config.go index 25b85d2..7f70c52 100644 --- a/pkg/sdk/assume_role_config.go +++ b/pkg/sdk/assume_role_config.go @@ -9,79 +9,3 @@ // The original source code contained in this file can be found at // https://github.com/hashicorp/terraform-provider-aws/blob/bbefb8dfad459bc1846038b1da4c5857afe55bd9/aws/provider.go#L1314 package sdk - -import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" - "log" -) - -func GetAssumeRoleConfig(d api.Getter) (config *AssumeRoleConfig) { - if l, ok := d.Get(KeyAssumeRole).([]interface{}); ok && len(l) > 0 && l[0] != nil { - config = &AssumeRoleConfig{} - - m := l[0].(map[string]interface{}) - - if v, ok := m["duration_seconds"].(int); ok && v != 0 { - config.DurationSeconds = int64(v) - } - - if v, ok := m["external_id"].(string); ok && v != "" { - config.ExternalID = v - } - - if v, ok := m["policy"].(string); ok && v != "" { - config.Policy = v - } - - if policyARNSet, ok := m["policy_arns"].(*schema.Set); ok && policyARNSet.Len() > 0 { - for _, policyARNRaw := range policyARNSet.List() { - policyARN, ok := policyARNRaw.(string) - - if !ok { - continue - } - - config.PolicyARNs = append(config.PolicyARNs, policyARN) - } - } - - if v, ok := m["role_arn"].(string); ok && v != "" { - config.RoleARN = v - } - - if v, ok := m["session_name"].(string); ok && v != "" { - config.SessionName = v - } - - if tagMapRaw, ok := m["tags"].(map[string]interface{}); ok && len(tagMapRaw) > 0 { - config.Tags = make(map[string]string) - - for k, vRaw := range tagMapRaw { - v, ok := vRaw.(string) - - if !ok { - continue - } - - config.Tags[k] = v - } - } - - if transitiveTagKeySet, ok := m["transitive_tag_keys"].(*schema.Set); ok && transitiveTagKeySet.Len() > 0 { - for _, transitiveTagKeyRaw := range transitiveTagKeySet.List() { - transitiveTagKey, ok := transitiveTagKeyRaw.(string) - - if !ok { - continue - } - - config.TransitiveTagKeys = append(config.TransitiveTagKeys, transitiveTagKey) - } - } - - log.Printf("[INFO] assume_role configuration set: (ARN: %q, SessionID: %q, ExternalID: %q)", config.RoleARN, config.SessionName, config.ExternalID) - } - - return -} diff --git a/pkg/sdk/aws_session.go b/pkg/sdk/aws_session.go index 6af85d6..6b2fed2 100644 --- a/pkg/sdk/aws_session.go +++ b/pkg/sdk/aws_session.go @@ -4,44 +4,9 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/session" - "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" "os" ) -func GetAWSRegionAndProfile(d api.Getter) (string, string) { - var region string - - if v := d.Get(KeyRegion); v != nil { - region = v.(string) - } - - var profile string - - if v := d.Get(KeyProfile); v != nil { - profile = v.(string) - } - - return region, profile -} - -func AWSSessionFromResourceData(d api.Getter) *session.Session { - region, profile := GetAWSRegionAndProfile(d) - - sess := NewSession(region, profile) - - assumeRoleConfig := GetAssumeRoleConfig(d) - if assumeRoleConfig == nil { - return sess - } - - newSess, _, err := AssumeRole(sess, *assumeRoleConfig) - if err != nil { - panic(err) - } - - return newSess -} - func AWSSession(region, profile string, assumeRoleConfig *AssumeRoleConfig) *session.Session { sess := NewSession(region, profile) diff --git a/pkg/sdk/job.go b/pkg/sdk/job.go new file mode 100644 index 0000000..7dd55dd --- /dev/null +++ b/pkg/sdk/job.go @@ -0,0 +1,43 @@ +package sdk + +import ( + "golang.org/x/xerrors" + "log" +) + +type Job struct { + ContextConfigFunc func() (string, string, *AssumeRoleConfig) +} + +func NewJob(f func() (string, string, *AssumeRoleConfig)) *Job { + return &Job{ContextConfigFunc: f} +} + +func (s *Job) Task(name string, f func(*Context) error) (err error) { + defer func() { + if err != nil { + log.Printf("Task %s failed due to error: %+v", name, err) + + err = xerrors.Errorf("task %s: %w", name, err) + + return + } + if e := recover(); e != nil { + log.Printf("Task %s failed due to panic: %+v", name, e) + + err = xerrors.Errorf("task %s: %w", name, e) + } + }() + + ctx := s.newContext() + + return f(ctx) +} + +func (s *Job) newContext() *Context { + region, profile, assumeRoleConfig := s.ContextConfigFunc() + + sess, creds := AWSCredsFromConfig(region, profile, assumeRoleConfig) + + return &Context{Sess: sess, Creds: creds} +} diff --git a/pkg/sdk/prepare_exec.go b/pkg/sdk/prepare_exec.go new file mode 100644 index 0000000..b7c9c4d --- /dev/null +++ b/pkg/sdk/prepare_exec.go @@ -0,0 +1,107 @@ +package sdk + +import ( + "bufio" + "fmt" + "github.com/mumoshu/shoal" + "golang.org/x/sync/errgroup" + "golang.org/x/xerrors" + "io" + "log" + "path/filepath" + "sync" +) + +var prepareExecMu sync.Mutex + +func PrepareExecutable(defaultPath, pkgAndCmdName, pkgVersion string) (*string, error) { + log.Printf("Preparing %s binary", pkgAndCmdName) + + conf := shoal.Config{ + Git: shoal.Git{ + Provider: "go-git", + }, + } + + rig := "https://github.com/fishworks/fish-food" + + installEksctl := pkgVersion != "" + + if installEksctl { + log.Printf("Installing %s %s", pkgAndCmdName, pkgVersion) + + conf.Dependencies = append(conf.Dependencies, + shoal.Dependency{ + Rig: rig, + Food: pkgAndCmdName, + Version: pkgVersion, + }, + ) + } + + log.Print("Started taking exclusive lock on shoal") + + prepareExecMu.Lock() + defer prepareExecMu.Unlock() + + log.Print("Took exclusive lock on shoal") + + logReader, logWriter := io.Pipe() + + s, err := shoal.New(shoal.LogOutput(logWriter)) + if err != nil { + return nil, err + } + + log.Print("Shoal instance created") + + if len(conf.Dependencies) > 0 { + eg := errgroup.Group{} + + scanner := bufio.NewScanner(logReader) + + eg.Go(func() error { + for scanner.Scan() { + log.Printf("shoal] %s", scanner.Text()) + } + + return nil + }) + + if err := s.Init(); err != nil { + return nil, fmt.Errorf("initializing shoal: %w", err) + } + + log.Print("Shoal initialized") + + if err := s.InitGitProvider(conf); err != nil { + return nil, fmt.Errorf("initializing shoal git provider: %w", err) + } + + log.Print("Shoal's Git provider initialized") + + eg.Go(func() error { + defer logWriter.Close() + + if err := s.Sync(conf); err != nil { + return xerrors.Errorf("running shoal-sync: %w", err) + } + + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, xerrors.Errorf("calling shoal: %w", err) + } + + log.Println("Shoal sync finished") + } + + binPath := s.BinPath() + + if pkgVersion != "" { + defaultPath = filepath.Join(binPath, pkgAndCmdName) + } + + return &defaultPath, nil +} diff --git a/pkg/sdk/tfsdk/assume_role_config_get.go b/pkg/sdk/tfsdk/assume_role_config_get.go new file mode 100644 index 0000000..d8cf5bf --- /dev/null +++ b/pkg/sdk/tfsdk/assume_role_config_get.go @@ -0,0 +1,78 @@ +package tfsdk + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + "log" +) + +func GetAssumeRoleConfig(d api.Getter) (config *sdk.AssumeRoleConfig) { + if l, ok := d.Get(KeyAssumeRole).([]interface{}); ok && len(l) > 0 && l[0] != nil { + config = &sdk.AssumeRoleConfig{} + + m := l[0].(map[string]interface{}) + + if v, ok := m["duration_seconds"].(int); ok && v != 0 { + config.DurationSeconds = int64(v) + } + + if v, ok := m["external_id"].(string); ok && v != "" { + config.ExternalID = v + } + + if v, ok := m["policy"].(string); ok && v != "" { + config.Policy = v + } + + if policyARNSet, ok := m["policy_arns"].(*schema.Set); ok && policyARNSet.Len() > 0 { + for _, policyARNRaw := range policyARNSet.List() { + policyARN, ok := policyARNRaw.(string) + + if !ok { + continue + } + + config.PolicyARNs = append(config.PolicyARNs, policyARN) + } + } + + if v, ok := m["role_arn"].(string); ok && v != "" { + config.RoleARN = v + } + + if v, ok := m["session_name"].(string); ok && v != "" { + config.SessionName = v + } + + if tagMapRaw, ok := m["tags"].(map[string]interface{}); ok && len(tagMapRaw) > 0 { + config.Tags = make(map[string]string) + + for k, vRaw := range tagMapRaw { + v, ok := vRaw.(string) + + if !ok { + continue + } + + config.Tags[k] = v + } + } + + if transitiveTagKeySet, ok := m["transitive_tag_keys"].(*schema.Set); ok && transitiveTagKeySet.Len() > 0 { + for _, transitiveTagKeyRaw := range transitiveTagKeySet.List() { + transitiveTagKey, ok := transitiveTagKeyRaw.(string) + + if !ok { + continue + } + + config.TransitiveTagKeys = append(config.TransitiveTagKeys, transitiveTagKey) + } + } + + log.Printf("[INFO] assume_role configuration set: (ARN: %q, SessionID: %q, ExternalID: %q)", config.RoleARN, config.SessionName, config.ExternalID) + } + + return +} diff --git a/pkg/sdk/tfsdk/aws_region_profile_get.go b/pkg/sdk/tfsdk/aws_region_profile_get.go new file mode 100644 index 0000000..08492e8 --- /dev/null +++ b/pkg/sdk/tfsdk/aws_region_profile_get.go @@ -0,0 +1,19 @@ +package tfsdk + +import "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" + +func GetAWSRegionAndProfile(d api.Getter) (string, string) { + var region string + + if v := d.Get(KeyRegion); v != nil { + region = v.(string) + } + + var profile string + + if v := d.Get(KeyProfile); v != nil { + profile = v.(string) + } + + return region, profile +} diff --git a/pkg/sdk/tfsdk/aws_session_get.go b/pkg/sdk/tfsdk/aws_session_get.go new file mode 100644 index 0000000..1199dd5 --- /dev/null +++ b/pkg/sdk/tfsdk/aws_session_get.go @@ -0,0 +1,25 @@ +package tfsdk + +import ( + "github.com/aws/aws-sdk-go/aws/session" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk" + "github.com/mumoshu/terraform-provider-eksctl/pkg/sdk/api" +) + +func AWSSessionFromResourceData(d api.Getter) *session.Session { + region, profile := GetAWSRegionAndProfile(d) + + sess := sdk.NewSession(region, profile) + + assumeRoleConfig := GetAssumeRoleConfig(d) + if assumeRoleConfig == nil { + return sess + } + + newSess, _, err := sdk.AssumeRole(sess, *assumeRoleConfig) + if err != nil { + panic(err) + } + + return newSess +} diff --git a/pkg/sdk/const.go b/pkg/sdk/tfsdk/constants.go similarity index 87% rename from pkg/sdk/const.go rename to pkg/sdk/tfsdk/constants.go index 203a832..1818366 100644 --- a/pkg/sdk/const.go +++ b/pkg/sdk/tfsdk/constants.go @@ -1,4 +1,4 @@ -package sdk +package tfsdk const ( KeyAssumeRole = "assume_role" diff --git a/pkg/sdk/tfsdk/diff_read_write.go b/pkg/sdk/tfsdk/diff_read_write.go new file mode 100644 index 0000000..73126c2 --- /dev/null +++ b/pkg/sdk/tfsdk/diff_read_write.go @@ -0,0 +1,27 @@ +package tfsdk + +import "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + +type DiffReadWrite struct { + D *schema.ResourceDiff +} + +func (d *DiffReadWrite) Get(k string) interface{} { + return d.D.Get(k) +} + +func (d *DiffReadWrite) List(k string) []interface{} { + return nil +} + +func (d *DiffReadWrite) Set(k string, v interface{}) error { + return d.D.SetNew(k, v) +} + +func (d *DiffReadWrite) SetNewComputed(k string) error { + return d.D.SetNewComputed(k) +} + +func (d *DiffReadWrite) Id() string { + return d.D.Id() +}