-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for resource gocd_backup_config and gocd_backup_schedule
- Loading branch information
1 parent
c2aa61b
commit 419a642
Showing
8 changed files
with
338 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ issues: | |
linters-settings: | ||
funlen: | ||
lines: 190 | ||
statements: 60 | ||
|
||
lll: | ||
line-length: 165 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
data "gocd_agent_config" "sample_agent" { | ||
uuid = "4c92e7e3-8abd-4b02-a7eb-c46b2c7ac674" | ||
uuid = "3bc47e62-eb8f-4c37-b082-1517f10ef7aa" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
resource "gocd_backup_config" "nightly_backup" { | ||
schedule = "0 0 2 * * ?" | ||
post_backup_script = "path/to/postbackup_script.sh" | ||
} | ||
|
||
resource "gocd_backup_schedule" "now" { | ||
schedule = true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package provider | ||
|
||
import ( | ||
"context" | ||
"log" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/nikhilsbhat/gocd-sdk-go" | ||
"github.com/nikhilsbhat/terraform-provider-gocd/pkg/utils" | ||
) | ||
|
||
func resourceBackupConfig() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourceBackupConfigCreate, | ||
ReadContext: resourceBackupConfigRead, | ||
UpdateContext: resourceBackupConfigUpdate, | ||
DeleteContext: resourceBackupConfigDelete, | ||
Schema: map[string]*schema.Schema{ | ||
"schedule": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Computed: false, | ||
Description: "The backup schedule. See the quartz documentation for syntax and examples.", | ||
}, | ||
"post_backup_script": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: false, | ||
Description: "The script that will be executed once the backup finishes. See the gocd documentation for details.", | ||
}, | ||
"email_on_success": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Computed: false, | ||
Description: "If set to true, an email will be sent when backup completes successfully.", | ||
}, | ||
"email_on_failure": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Computed: false, | ||
Description: "If set to true, an email will be sent when backup fails.", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceBackupConfigCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
defaultConfig := meta.(gocd.GoCd) | ||
|
||
if !d.IsNewResource() { | ||
return nil | ||
} | ||
|
||
id := d.Id() | ||
|
||
if len(id) == 0 { | ||
resourceID := utils.String(d.Get(utils.TerraformResourceSchedule)) | ||
id = resourceID | ||
} | ||
|
||
cfg := gocd.BackupConfig{ | ||
Schedule: utils.String(d.Get(utils.TerraformResourceSchedule)), | ||
PostBackupScript: utils.String(d.Get(utils.TerraformResourcePostBackupScript)), | ||
EmailOnSuccess: utils.Bool(d.Get(utils.TerraformResourceEmailOnSuccess)), | ||
EmailOnFailure: utils.Bool(d.Get(utils.TerraformResourceEmailOnFailure)), | ||
} | ||
|
||
if err := defaultConfig.CreateOrUpdateBackupConfig(cfg); err != nil { | ||
return diag.Errorf("creating backup configuration errored with %v", err) | ||
} | ||
|
||
d.SetId(id) | ||
|
||
return resourceBackupConfigRead(ctx, d, meta) | ||
} | ||
|
||
func resourceBackupConfigRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
defaultConfig := meta.(gocd.GoCd) | ||
|
||
response, err := defaultConfig.GetBackupConfig() | ||
if err != nil { | ||
return diag.Errorf("getting backup configuration errored with: %v", err) | ||
} | ||
|
||
if err = d.Set(utils.TerraformResourceSchedule, response.Schedule); err != nil { | ||
return diag.Errorf(settingAttrErrorTmp, utils.TerraformResourceSchedule, err) | ||
} | ||
|
||
if err = d.Set(utils.TerraformResourcePostBackupScript, response.PostBackupScript); err != nil { | ||
return diag.Errorf(settingAttrErrorTmp, utils.TerraformResourcePostBackupScript, err) | ||
} | ||
|
||
if err = d.Set(utils.TerraformResourceEmailOnSuccess, response.EmailOnSuccess); err != nil { | ||
return diag.Errorf(settingAttrErrorTmp, utils.TerraformResourceEmailOnSuccess, err) | ||
} | ||
|
||
if err = d.Set(utils.TerraformResourceEmailOnFailure, response.EmailOnFailure); err != nil { | ||
return diag.Errorf(settingAttrErrorTmp, utils.TerraformResourceEmailOnFailure, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceBackupConfigUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
defaultConfig := meta.(gocd.GoCd) | ||
|
||
if !d.HasChanges( | ||
utils.TerraformResourceSchedule, | ||
utils.TerraformResourcePostBackupScript, | ||
utils.TerraformResourceEmailOnSuccess, | ||
utils.TerraformResourceEmailOnFailure, | ||
) { | ||
log.Printf("nothing to update so skipping") | ||
|
||
return nil | ||
} | ||
|
||
cfg := gocd.BackupConfig{ | ||
Schedule: utils.String(d.Get(utils.TerraformResourceSchedule)), | ||
PostBackupScript: utils.String(d.Get(utils.TerraformResourcePostBackupScript)), | ||
EmailOnSuccess: utils.Bool(d.Get(utils.TerraformResourceEmailOnSuccess)), | ||
EmailOnFailure: utils.Bool(d.Get(utils.TerraformResourceEmailOnFailure)), | ||
} | ||
|
||
if err := defaultConfig.CreateOrUpdateBackupConfig(cfg); err != nil { | ||
return diag.Errorf("updating backup configuration errored with %v", err) | ||
} | ||
|
||
return resourceBackupConfigRead(ctx, d, meta) | ||
} | ||
|
||
func resourceBackupConfigDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
defaultConfig := meta.(gocd.GoCd) | ||
|
||
id := d.Id() | ||
if len(d.Id()) == 0 { | ||
return diag.Errorf("resource with the ID '%s' not found", id) | ||
} | ||
|
||
err := defaultConfig.DeleteBackupConfig() | ||
if err != nil { | ||
return diag.Errorf("deleting backup configuration errored with: %v", err) | ||
} | ||
|
||
d.SetId("") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
package provider | ||
|
||
import ( | ||
"context" | ||
"log" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/nikhilsbhat/gocd-sdk-go" | ||
"github.com/nikhilsbhat/terraform-provider-gocd/pkg/utils" | ||
) | ||
|
||
func resourceBackupSchedule() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourceBackupScheduleCreate, | ||
ReadContext: resourceBackupScheduleRead, | ||
DeleteContext: resourceBackupScheduleDelete, | ||
Schema: map[string]*schema.Schema{ | ||
"schedule": { | ||
Type: schema.TypeBool, | ||
Required: true, | ||
Computed: false, | ||
ForceNew: true, | ||
Description: "Enable to trigger the backup, (would be unset post backup is successful).", | ||
}, | ||
"retry": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Computed: false, | ||
Default: defaultRetry, | ||
ForceNew: true, | ||
Description: "Number of times to retry to get the ID of latest successful backup taken.", | ||
}, | ||
"delay": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Computed: false, | ||
Default: defaultDelay, | ||
ForceNew: true, | ||
Description: "Time delay between each retries that would be made to get backup stats (in seconds ex: 5).", | ||
}, | ||
"retry_after": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Computed: true, | ||
Description: "This would be set to handle the backup scheduling internally.", | ||
}, | ||
"backup_id": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
Description: "Id of the backup that was taken successfully", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
var ( | ||
defaultRetry = 30 | ||
defaultDelay = 5 | ||
) | ||
|
||
func resourceBackupScheduleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
defaultConfig := meta.(gocd.GoCd) | ||
|
||
if !d.IsNewResource() { | ||
return nil | ||
} | ||
|
||
var id string | ||
|
||
newID, err := utils.GetRandomID() | ||
if err != nil { | ||
d.SetId("") | ||
|
||
return diag.Errorf("errored while fetching randomID %v", err) | ||
} | ||
id = newID | ||
|
||
if !utils.Bool(d.Get(utils.TerraformResourceSchedule)) { | ||
return diag.Errorf("scheduling backup is disabled, set attribute '%s' to true to schedule a backup", utils.TerraformResourceSchedule) | ||
} | ||
|
||
response, err := defaultConfig.ScheduleBackup() | ||
if err != nil { | ||
return diag.Errorf("scheduling backup errored with: %v", err) | ||
} | ||
|
||
retryAfter, err := strconv.Atoi(response["RetryAfter"]) | ||
if err != nil { | ||
return diag.Errorf("%v", err) | ||
} | ||
|
||
if err = d.Set(utils.TerraformResourceBackupID, response["BackUpID"]); err != nil { | ||
return diag.Errorf(settingAttrErrorTmp, utils.TerraformResourceBackupID, err) | ||
} | ||
|
||
if err = d.Set(utils.TerraformResourceRetryAfter, retryAfter); err != nil { | ||
return diag.Errorf(settingAttrErrorTmp, utils.TerraformResourceRetryAfter, err) | ||
} | ||
|
||
d.SetId(id) | ||
|
||
return resourceBackupScheduleRead(ctx, d, meta) | ||
} | ||
|
||
func resourceBackupScheduleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
defaultConfig := meta.(gocd.GoCd) | ||
|
||
retryAfter := d.Get(utils.TerraformResourceRetryAfter).(int) | ||
backupRetry := d.Get(utils.TerraformResourceRetry).(int) | ||
delayCount := d.Get(utils.TerraformResourceDelay).(int) | ||
backupID := utils.String(d.Get(utils.TerraformResourceBackupID)) | ||
|
||
delay := time.Duration(delayCount) * time.Second | ||
|
||
time.Sleep(time.Duration(retryAfter) * time.Second) | ||
currentRetryCount := 0 | ||
var latestBackupStatus string | ||
for { | ||
if currentRetryCount > backupRetry { | ||
return diag.Errorf("maximum retry count of '%d' crossed with current count '%d', still backup is not ready yet with status '%s'. Exiting", | ||
backupRetry, currentRetryCount, latestBackupStatus) | ||
} | ||
|
||
response, err := defaultConfig.GetBackup(backupID) | ||
if err != nil { | ||
return diag.Errorf("getting last configured backup ID errored with: %v", err) | ||
} | ||
|
||
retryRemaining := backupRetry - currentRetryCount | ||
if response.Status == "IN_PROGRESS" { | ||
log.Printf("the backup stats is still in IN_PROGRESS status, retrying... '%d' more to go", retryRemaining) | ||
} | ||
|
||
if response.Status == "COMPLETED" { | ||
if err = d.Set(utils.TerraformResourceSchedule, false); err != nil { | ||
return diag.Errorf(settingAttrErrorTmp, utils.TerraformResourceSchedule, err) | ||
} | ||
|
||
break | ||
} | ||
|
||
if response.Status != "COMPLETED" && response.Status != "IN_PROGRESS" { | ||
return diag.Errorf("looks like backup status is neither IN_PROGRESS nor COMPLETED rather it is %s", response.Status) | ||
} | ||
|
||
latestBackupStatus = response.Status | ||
time.Sleep(delay) | ||
currentRetryCount++ | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceBackupScheduleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
id := d.Id() | ||
if len(d.Id()) == 0 { | ||
return diag.Errorf("resource with the ID '%s' not found", id) | ||
} | ||
|
||
d.SetId("") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters