github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/ibm/instance_groups.go (about) 1 // Copyright 2019 The Terraformer Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ibm 16 17 import ( 18 "fmt" 19 "math/rand" 20 "os" 21 "sync" 22 23 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 24 "github.com/IBM/go-sdk-core/v4/core" 25 "github.com/IBM/vpc-go-sdk/vpcv1" 26 ) 27 28 // InstanceGroupGenerator ... 29 type InstanceGroupGenerator struct { 30 IBMService 31 fatalErrors chan error 32 } 33 34 func (g *InstanceGroupGenerator) loadInstanceGroup(instanceGroupID, instanceGroupName string) terraformutils.Resource { 35 resources := terraformutils.NewSimpleResource( 36 instanceGroupID, 37 instanceGroupName, 38 "ibm_is_instance_group", 39 "ibm", 40 []string{}) 41 return resources 42 } 43 44 func (g *InstanceGroupGenerator) loadInstanceGroupManger(instanceGroupID, instanceGroupManagerID, managerName string, dependsOn []string) terraformutils.Resource { 45 if managerName == "" { 46 managerName = fmt.Sprintf("manager-%d-%d", rand.Intn(100), rand.Intn(50)) 47 } 48 resources := terraformutils.NewResource( 49 fmt.Sprintf("%s/%s", instanceGroupID, instanceGroupManagerID), 50 managerName, 51 "ibm_is_instance_group_manager", 52 "ibm", 53 map[string]string{}, 54 []string{}, 55 map[string]interface{}{ 56 "depends_on": dependsOn, 57 }) 58 return resources 59 } 60 61 func (g *InstanceGroupGenerator) loadInstanceGroupMangerPolicy(instanceGroupID, instanceGroupManagerID, policyID, policyName string, dependsOn []string) terraformutils.Resource { 62 if policyName == "" { 63 policyName = fmt.Sprintf("manager-%d-%d", rand.Intn(100), rand.Intn(50)) 64 } 65 resources := terraformutils.NewResource( 66 fmt.Sprintf("%s/%s/%s", instanceGroupID, instanceGroupManagerID, policyID), 67 policyName, 68 "ibm_is_instance_group_manager_policy", 69 "ibm", 70 map[string]string{}, 71 []string{}, 72 map[string]interface{}{ 73 "depends_on": dependsOn, 74 }) 75 return resources 76 } 77 78 func (g *InstanceGroupGenerator) handlePolicies(sess *vpcv1.VpcV1, instanceGroupID, instanceGroupManagerID string, policies, dependsOn []string, waitGroup *sync.WaitGroup) { 79 defer waitGroup.Done() 80 for _, instanceGroupManagerPolicyID := range policies { 81 getInstanceGroupManagerPolicyOptions := vpcv1.GetInstanceGroupManagerPolicyOptions{ 82 ID: &instanceGroupManagerPolicyID, 83 InstanceGroupID: &instanceGroupID, 84 InstanceGroupManagerID: &instanceGroupManagerID, 85 } 86 data, response, err := sess.GetInstanceGroupManagerPolicy(&getInstanceGroupManagerPolicyOptions) 87 if err != nil { 88 g.fatalErrors <- fmt.Errorf("Error Getting InstanceGroup Manager Policy: %s\n%s", err, response) 89 } 90 instanceGroupManagerPolicy := data.(*vpcv1.InstanceGroupManagerPolicy) 91 g.Resources = append(g.Resources, g.loadInstanceGroupMangerPolicy(instanceGroupID, 92 instanceGroupManagerID, 93 instanceGroupManagerPolicyID, 94 *instanceGroupManagerPolicy.Name, 95 dependsOn)) 96 } 97 } 98 99 func (g *InstanceGroupGenerator) handleManagers(sess *vpcv1.VpcV1, instanceGroupID string, managers, dependsOn []string, waitGroup *sync.WaitGroup) { 100 defer waitGroup.Done() 101 var policiesWG sync.WaitGroup 102 for _, instanceGroupManagerID := range managers { 103 getInstanceGroupManagerOptions := vpcv1.GetInstanceGroupManagerOptions{ 104 ID: &instanceGroupManagerID, 105 InstanceGroupID: &instanceGroupID, 106 } 107 instanceGroupManager, response, err := sess.GetInstanceGroupManager(&getInstanceGroupManagerOptions) 108 if err != nil { 109 g.fatalErrors <- fmt.Errorf("Error Getting InstanceGroup Manager: %s\n%s", err, response) 110 } 111 g.Resources = append(g.Resources, g.loadInstanceGroupManger(instanceGroupID, instanceGroupManagerID, *instanceGroupManager.Name, dependsOn)) 112 113 policies := make([]string, 0) 114 115 for i := 0; i < len(instanceGroupManager.Policies); i++ { 116 policies = append(policies, *(instanceGroupManager.Policies[i].ID)) 117 } 118 policiesWG.Add(1) 119 dependsOn1 := makeDependsOn(dependsOn, 120 "ibm_is_instance_group_manger."+terraformutils.TfSanitize(*instanceGroupManager.Name)) 121 go g.handlePolicies(sess, instanceGroupID, instanceGroupManagerID, policies, dependsOn1, &policiesWG) 122 } 123 policiesWG.Wait() 124 } 125 126 func (g *InstanceGroupGenerator) handleInstanceGroups(sess *vpcv1.VpcV1, waitGroup *sync.WaitGroup) { 127 // Support for pagination 128 defer waitGroup.Done() 129 start := "" 130 var allrecs []vpcv1.InstanceGroup 131 for { 132 listInstanceGroupOptions := vpcv1.ListInstanceGroupsOptions{} 133 if start != "" { 134 listInstanceGroupOptions.Start = &start 135 } 136 instanceGroupsCollection, response, err := sess.ListInstanceGroups(&listInstanceGroupOptions) 137 if err != nil { 138 g.fatalErrors <- fmt.Errorf("Error Fetching InstanceGroups %s\n%s", err, response) 139 } 140 start = GetNext(instanceGroupsCollection.Next) 141 allrecs = append(allrecs, instanceGroupsCollection.InstanceGroups...) 142 if start == "" { 143 break 144 } 145 } 146 147 var managersWG sync.WaitGroup 148 149 for _, instanceGroup := range allrecs { 150 var dependsOn []string 151 dependsOn = append(dependsOn, 152 "ibm_is_instance_group."+terraformutils.TfSanitize(*instanceGroup.Name)) 153 instanceGoupID := *instanceGroup.ID 154 g.Resources = append(g.Resources, g.loadInstanceGroup(instanceGoupID, *instanceGroup.Name)) 155 managers := make([]string, 0) 156 for i := 0; i < len(instanceGroup.Managers); i++ { 157 managers = append(managers, *(instanceGroup.Managers[i].ID)) 158 } 159 managersWG.Add(1) 160 go g.handleManagers(sess, instanceGoupID, managers, dependsOn, &managersWG) 161 } 162 managersWG.Wait() 163 } 164 165 // InitResources ... 166 func (g *InstanceGroupGenerator) InitResources() error { 167 apiKey := os.Getenv("IC_API_KEY") 168 if apiKey == "" { 169 return fmt.Errorf("no API key set") 170 } 171 172 // Instantiate the service with an API key based IAM authenticator 173 sess, err := vpcv1.NewVpcV1(&vpcv1.VpcV1Options{ 174 Authenticator: &core.IamAuthenticator{ 175 ApiKey: apiKey, 176 }, 177 }) 178 if err != nil { 179 return err 180 } 181 182 g.fatalErrors = make(chan error) 183 184 var instanceGroupWG sync.WaitGroup 185 instanceGroupWG.Add(1) 186 go g.handleInstanceGroups(sess, &instanceGroupWG) 187 188 select { //nolint 189 case err := <-g.fatalErrors: 190 close(g.fatalErrors) 191 return err 192 } 193 instanceGroupWG.Wait() //nolint:govet 194 return nil 195 }