|
| 1 | +package google |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "log" |
| 6 | + "reflect" |
| 7 | + "time" |
| 8 | + |
| 9 | + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" |
| 10 | +) |
| 11 | + |
| 12 | +func ResourceApigeeFlowhook() *schema.Resource { |
| 13 | + return &schema.Resource{ |
| 14 | + Create: resourceApigeeFlowhookCreate, |
| 15 | + Read: resourceApigeeFlowhookRead, |
| 16 | + Delete: resourceApigeeFlowhookDelete, |
| 17 | + |
| 18 | + Importer: &schema.ResourceImporter{ |
| 19 | + State: resourceApigeeFlowhookImport, |
| 20 | + }, |
| 21 | + |
| 22 | + Timeouts: &schema.ResourceTimeout{ |
| 23 | + Create: schema.DefaultTimeout(20 * time.Minute), |
| 24 | + Delete: schema.DefaultTimeout(20 * time.Minute), |
| 25 | + }, |
| 26 | + |
| 27 | + Schema: map[string]*schema.Schema{ |
| 28 | + "description": { |
| 29 | + Type: schema.TypeString, |
| 30 | + Optional: true, |
| 31 | + ForceNew: true, |
| 32 | + Description: `Description of the flow hook.`, |
| 33 | + }, |
| 34 | + "environment": { |
| 35 | + Type: schema.TypeString, |
| 36 | + Required: true, |
| 37 | + ForceNew: true, |
| 38 | + Description: `The resource ID of the environment.`, |
| 39 | + }, |
| 40 | + "flow_hook_point": { |
| 41 | + Type: schema.TypeString, |
| 42 | + Required: true, |
| 43 | + ForceNew: true, |
| 44 | + Description: `Where in the API call flow the flow hook is invoked. Must be one of PreProxyFlowHook, PostProxyFlowHook, PreTargetFlowHook, or PostTargetFlowHook.`, |
| 45 | + }, |
| 46 | + "org_id": { |
| 47 | + Type: schema.TypeString, |
| 48 | + Required: true, |
| 49 | + ForceNew: true, |
| 50 | + Description: `The Apigee Organization associated with the environment`, |
| 51 | + }, |
| 52 | + "sharedflow": { |
| 53 | + Type: schema.TypeString, |
| 54 | + Required: true, |
| 55 | + ForceNew: true, |
| 56 | + Description: `Id of the Sharedflow attaching to a flowhook point.`, |
| 57 | + }, |
| 58 | + "continue_on_error": { |
| 59 | + Type: schema.TypeBool, |
| 60 | + ForceNew: true, |
| 61 | + Optional: true, |
| 62 | + Default: true, |
| 63 | + Description: `Flag that specifies whether execution should continue if the flow hook throws an exception. Set to true to continue execution. Set to false to stop execution if the flow hook throws an exception. Defaults to true.`, |
| 64 | + }, |
| 65 | + }, |
| 66 | + UseJSONNumber: true, |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +func resourceApigeeFlowhookCreate(d *schema.ResourceData, meta interface{}) error { |
| 71 | + config := meta.(*Config) |
| 72 | + userAgent, err := generateUserAgentString(d, config.UserAgent) |
| 73 | + if err != nil { |
| 74 | + return err |
| 75 | + } |
| 76 | + |
| 77 | + obj := make(map[string]interface{}) |
| 78 | + descriptionProp, err := expandApigeeFlowhookDescription(d.Get("description"), d, config) |
| 79 | + if err != nil { |
| 80 | + return err |
| 81 | + } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { |
| 82 | + obj["description"] = descriptionProp |
| 83 | + } |
| 84 | + sharedflowProp, err := expandApigeeFlowhookSharedflow(d.Get("sharedflow"), d, config) |
| 85 | + if err != nil { |
| 86 | + return err |
| 87 | + } else if v, ok := d.GetOkExists("sharedflow"); !isEmptyValue(reflect.ValueOf(sharedflowProp)) && (ok || !reflect.DeepEqual(v, sharedflowProp)) { |
| 88 | + obj["sharedFlow"] = sharedflowProp |
| 89 | + } |
| 90 | + continue_on_errorProp, err := expandApigeeFlowhookContinueOnError(d.Get("continue_on_error"), d, config) |
| 91 | + if err != nil { |
| 92 | + return err |
| 93 | + } else if v, ok := d.GetOkExists("continue_on_error"); !isEmptyValue(reflect.ValueOf(continue_on_errorProp)) && (ok || !reflect.DeepEqual(v, continue_on_errorProp)) { |
| 94 | + obj["continueOnError"] = continue_on_errorProp |
| 95 | + } |
| 96 | + |
| 97 | + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") |
| 98 | + if err != nil { |
| 99 | + return err |
| 100 | + } |
| 101 | + |
| 102 | + log.Printf("[DEBUG] Creating new Flowhook: %#v", obj) |
| 103 | + billingProject := "" |
| 104 | + |
| 105 | + // err == nil indicates that the billing_project value was found |
| 106 | + if bp, err := getBillingProject(d, config); err == nil { |
| 107 | + billingProject = bp |
| 108 | + } |
| 109 | + |
| 110 | + res, err := SendRequestWithTimeout(config, "PUT", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) |
| 111 | + if err != nil { |
| 112 | + return fmt.Errorf("Error creating Flowhook: %s", err) |
| 113 | + } |
| 114 | + |
| 115 | + // Store the ID now |
| 116 | + id, err := replaceVars(d, config, "organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") |
| 117 | + if err != nil { |
| 118 | + return fmt.Errorf("Error constructing id: %s", err) |
| 119 | + } |
| 120 | + d.SetId(id) |
| 121 | + |
| 122 | + log.Printf("[DEBUG] Finished creating Flowhook %q: %#v", d.Id(), res) |
| 123 | + |
| 124 | + return resourceApigeeFlowhookRead(d, meta) |
| 125 | +} |
| 126 | + |
| 127 | +func resourceApigeeFlowhookRead(d *schema.ResourceData, meta interface{}) error { |
| 128 | + config := meta.(*Config) |
| 129 | + userAgent, err := generateUserAgentString(d, config.UserAgent) |
| 130 | + if err != nil { |
| 131 | + return err |
| 132 | + } |
| 133 | + |
| 134 | + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") |
| 135 | + if err != nil { |
| 136 | + return err |
| 137 | + } |
| 138 | + |
| 139 | + billingProject := "" |
| 140 | + |
| 141 | + // err == nil indicates that the billing_project value was found |
| 142 | + if bp, err := getBillingProject(d, config); err == nil { |
| 143 | + billingProject = bp |
| 144 | + } |
| 145 | + |
| 146 | + res, err := SendRequest(config, "GET", billingProject, url, userAgent, nil) |
| 147 | + if err != nil { |
| 148 | + return handleNotFoundError(err, d, fmt.Sprintf("ApigeeFlowhook %q", d.Id())) |
| 149 | + } |
| 150 | + if res["sharedFlow"] == nil || res["sharedFlow"].(string) == "" { |
| 151 | + //if response does not contain shared_flow field, then nothing is attached to this flowhook, we treat this "binding" resource non-existent |
| 152 | + d.SetId("") |
| 153 | + return nil |
| 154 | + } |
| 155 | + if err := d.Set("description", flattenApigeeFlowhookDescription(res["description"], d, config)); err != nil { |
| 156 | + return fmt.Errorf("Error reading Flowhook: %s", err) |
| 157 | + } |
| 158 | + if err := d.Set("sharedflow", flattenApigeeFlowhookSharedflow(res["sharedFlow"], d, config)); err != nil { |
| 159 | + return fmt.Errorf("Error reading Flowhook: %s", err) |
| 160 | + } |
| 161 | + if err := d.Set("continue_on_error", flattenApigeeFlowhookContinueOnError(res["continueOnError"], d, config)); err != nil { |
| 162 | + return fmt.Errorf("Error reading Flowhook: %s", err) |
| 163 | + } |
| 164 | + |
| 165 | + return nil |
| 166 | +} |
| 167 | + |
| 168 | +func resourceApigeeFlowhookDelete(d *schema.ResourceData, meta interface{}) error { |
| 169 | + config := meta.(*Config) |
| 170 | + userAgent, err := generateUserAgentString(d, config.UserAgent) |
| 171 | + if err != nil { |
| 172 | + return err |
| 173 | + } |
| 174 | + |
| 175 | + billingProject := "" |
| 176 | + |
| 177 | + url, err := replaceVars(d, config, "{{ApigeeBasePath}}organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") |
| 178 | + if err != nil { |
| 179 | + return err |
| 180 | + } |
| 181 | + |
| 182 | + var obj map[string]interface{} |
| 183 | + log.Printf("[DEBUG] Deleting Flowhook %q", d.Id()) |
| 184 | + |
| 185 | + // err == nil indicates that the billing_project value was found |
| 186 | + if bp, err := getBillingProject(d, config); err == nil { |
| 187 | + billingProject = bp |
| 188 | + } |
| 189 | + |
| 190 | + res, err := SendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) |
| 191 | + if err != nil { |
| 192 | + return handleNotFoundError(err, d, "Flowhook") |
| 193 | + } |
| 194 | + |
| 195 | + log.Printf("[DEBUG] Finished deleting Flowhook %q: %#v", d.Id(), res) |
| 196 | + return nil |
| 197 | +} |
| 198 | + |
| 199 | +func resourceApigeeFlowhookImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { |
| 200 | + config := meta.(*Config) |
| 201 | + if err := parseImportId([]string{ |
| 202 | + "organizations/(?P<org_id>[^/]+)/environments/(?P<environment>[^/]+)/flowhooks/(?P<flow_hook_point>[^/]+)", |
| 203 | + "(?P<org_id>[^/]+)/(?P<environment>[^/]+)/(?P<flow_hook_point>[^/]+)", |
| 204 | + }, d, config); err != nil { |
| 205 | + return nil, err |
| 206 | + } |
| 207 | + |
| 208 | + // Replace import id for the resource id |
| 209 | + id, err := replaceVars(d, config, "organizations/{{org_id}}/environments/{{environment}}/flowhooks/{{flow_hook_point}}") |
| 210 | + if err != nil { |
| 211 | + return nil, fmt.Errorf("Error constructing id: %s", err) |
| 212 | + } |
| 213 | + d.SetId(id) |
| 214 | + |
| 215 | + return []*schema.ResourceData{d}, nil |
| 216 | +} |
| 217 | + |
| 218 | +func flattenApigeeFlowhookDescription(v interface{}, d *schema.ResourceData, config *Config) interface{} { |
| 219 | + return v |
| 220 | +} |
| 221 | + |
| 222 | +func flattenApigeeFlowhookSharedflow(v interface{}, d *schema.ResourceData, config *Config) interface{} { |
| 223 | + return v |
| 224 | +} |
| 225 | + |
| 226 | +func flattenApigeeFlowhookContinueOnError(v interface{}, d *schema.ResourceData, config *Config) interface{} { |
| 227 | + return v |
| 228 | +} |
| 229 | + |
| 230 | +func expandApigeeFlowhookDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { |
| 231 | + return v, nil |
| 232 | +} |
| 233 | + |
| 234 | +func expandApigeeFlowhookSharedflow(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { |
| 235 | + return v, nil |
| 236 | +} |
| 237 | + |
| 238 | +func expandApigeeFlowhookContinueOnError(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { |
| 239 | + return v, nil |
| 240 | +} |
0 commit comments