in internal/provider/sdk/resource_gitlab_group.go [378:588]
func resourceGitlabGroupCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
client := meta.(*gitlab.Client)
options := &gitlab.CreateGroupOptions{
Name: gitlab.Ptr(d.Get("name").(string)),
}
if v, ok := d.GetOk("path"); ok {
options.Path = gitlab.Ptr(v.(string))
}
if v, ok := d.GetOk("default_branch"); ok {
options.DefaultBranch = gitlab.Ptr(v.(string))
}
if v, ok := d.GetOk("description"); ok {
options.Description = gitlab.Ptr(v.(string))
}
if v, ok := d.GetOk("visibility_level"); ok {
options.Visibility = stringToVisibilityLevel(v.(string))
}
if v, ok := d.GetOk("share_with_group_lock"); ok {
options.ShareWithGroupLock = gitlab.Ptr(v.(bool))
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("lfs_enabled"); ok {
options.LFSEnabled = gitlab.Ptr(v.(bool))
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("request_access_enabled"); ok {
options.RequestAccessEnabled = gitlab.Ptr(v.(bool))
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("require_two_factor_authentication"); ok {
options.RequireTwoFactorAuth = gitlab.Ptr(v.(bool))
}
if v, ok := d.GetOk("two_factor_grace_period"); ok {
options.TwoFactorGracePeriod = gitlab.Ptr(v.(int))
}
if v, ok := d.GetOk("project_creation_level"); ok {
options.ProjectCreationLevel = stringToProjectCreationLevel(v.(string))
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("auto_devops_enabled"); ok {
options.AutoDevopsEnabled = gitlab.Ptr(v.(bool))
}
if v, ok := d.GetOk("subgroup_creation_level"); ok {
options.SubGroupCreationLevel = stringToSubGroupCreationLevel(v.(string))
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("emails_enabled"); ok {
options.EmailsEnabled = gitlab.Ptr(v.(bool))
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("mentions_disabled"); ok {
options.MentionsDisabled = gitlab.Ptr(v.(bool))
}
if v, ok := d.GetOk("parent_id"); ok {
options.ParentID = gitlab.Ptr(v.(int))
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("default_branch_protection"); ok {
options.DefaultBranchProtection = gitlab.Ptr(v.(int))
}
if v, ok := d.GetOk("default_branch_protection_defaults.0"); ok {
defaults := v.(map[string]any)
options.DefaultBranchProtectionDefaults = &gitlab.DefaultBranchProtectionDefaultsOptions{
AllowedToPush: gitlab.Ptr(convertAccessLevelNamesToValues(defaults["allowed_to_push"].([]any))),
AllowForcePush: gitlab.Ptr(defaults["allow_force_push"].(bool)),
AllowedToMerge: gitlab.Ptr(convertAccessLevelNamesToValues(defaults["allowed_to_merge"].([]any))),
DeveloperCanInitialPush: gitlab.Ptr(defaults["developer_can_initial_push"].(bool)),
}
}
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("membership_lock"); ok {
options.MembershipLock = gitlab.Ptr(v.(bool))
}
if v, ok := d.GetOk("extra_shared_runners_minutes_limit"); ok {
options.ExtraSharedRunnersMinutesLimit = gitlab.Ptr(v.(int))
}
if v, ok := d.GetOk("shared_runners_minutes_limit"); ok {
options.SharedRunnersMinutesLimit = gitlab.Ptr(v.(int))
}
avatar, err := handleAvatarOnCreate(d)
if err != nil {
return diag.FromErr(err)
}
if avatar != nil {
options.Avatar = &gitlab.GroupAvatar{
Filename: avatar.Filename,
Image: avatar.Image,
}
}
if v, ok := d.GetOk("wiki_access_level"); ok {
options.WikiAccessLevel = stringToAccessControlValue(v.(string))
}
tflog.Debug(ctx, "[DEBUG] create gitlab group", map[string]any{
"name": *options.Name,
})
group, _, err := client.Groups.CreateGroup(options, gitlab.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}
// Wait for the Group to return properly before we update it
// Groups are created asynchronously, so we want to ensure the create operation
// completely finishes before we act on the group, or we can get an error.
// see: https://gitlab.com/gitlab-org/terraform-provider-gitlab/-/issues/692
stateConf := &retry.StateChangeConf{
Pending: []string{"Creating"},
Target: []string{"Created"},
Refresh: func() (any, string, error) {
out, _, err := client.Groups.GetGroup(group.ID, nil, gitlab.WithContext(ctx))
if err != nil {
if api.Is404(err) {
return out, "Creating", nil
}
tflog.Error(ctx, "[ERROR] Received error retrieving group", map[string]any{
"group_id": group.ID,
"error": err,
})
return out, "Error", err
}
return out, "Created", nil
},
Timeout: d.Timeout(schema.TimeoutCreate),
MinTimeout: 3 * time.Second,
Delay: 5 * time.Second,
}
_, err = stateConf.WaitForStateContext(ctx)
if err != nil {
return diag.Errorf("error waiting for group (%s) to create: %s", d.Id(), err)
}
// Our group has been created, we can now update it.
d.SetId(fmt.Sprintf("%d", group.ID))
if _, ok := d.GetOk("push_rules"); ok {
err := editOrAddGroupPushRules(ctx, client, d.Id(), d)
if err != nil {
if api.Is404(err) {
tflog.Error(ctx, "[ERROR] Failed to edit push rules for group", map[string]any{
"group_id": d.Id(),
"error": err,
})
return diag.Errorf("Group push rules are not supported in your version of GitLab")
}
return diag.Errorf("Failed to edit push rules for group %q: %s", d.Id(), err)
}
}
var updateOptions gitlab.UpdateGroupOptions
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
if v, ok := d.GetOkExists("prevent_forking_outside_group"); ok {
updateOptions.PreventForkingOutsideGroup = gitlab.Ptr(v.(bool))
}
// IP Restriction can only be set on update.
if v, ok := d.GetOk("ip_restriction_ranges"); ok {
updateOptions.IPRestrictionRanges = stringListToCommaSeparatedString(v.([]any))
}
// Email domains can only be set on update.
if v, ok := d.GetOk("allowed_email_domains_list"); ok {
updateOptions.AllowedEmailDomainsList = stringListToCommaSeparatedString(v.([]any))
}
if v, ok := d.GetOk("shared_runners_setting"); ok {
updateOptions.SharedRunnersSetting = stringToSharedRunnersSetting(v.(string))
}
if (updateOptions != gitlab.UpdateGroupOptions{}) {
if _, _, err = client.Groups.UpdateGroup(d.Id(), &updateOptions, gitlab.WithContext(ctx)); err != nil {
return diag.Errorf("could not update group after creation %q: %s", d.Id(), err)
}
}
return resourceGitlabGroupRead(ctx, d, meta)
}