Skip to content

Commit 1455db0

Browse files
Add managed license resources and tests (#700)
* Add managed license resources and tests * Add documentation for the managed_license resource * Update to v2 schema using context This involves several updates: 1. Update the schema.Resource to the "Context" method; 2. Pass in context to each of the functions and update returns to "diagnostic" type; 3. Pass in context to each of the client calls. * Add import statement and update tests accordingly In addition, I added the import statement the documentation and renamed the documentation filename to remove the "gitlab_" from the front which now matches the convention of the remainder of the documentation. * Pass through updating documentation to new standards and using new SkipFunc * Fixed several issues with tests. Implemented specific importer methods. The importer passthrough method seemed to break on the multi-ID needed for the project:license pair. * Rename license variable from "id" to "licenseId" * Update import to use StatePassthroughContext This also required updating the CRUD methods to accept a 2 part string and parse out the ID * Remove dead code. * Remove random license name * Apply suggestion re: removing from state if it doesn't exist in upsteam Co-authored-by: Adam Snyder <[email protected]> * Add callout re: Ultimate subscription and comments to the import.sh * Properly generate documentation for pr-lint. * Added second newline and re-generated documentation. Co-authored-by: Adam Snyder <[email protected]>
1 parent fa533d2 commit 1455db0

File tree

6 files changed

+391
-0
lines changed

6 files changed

+391
-0
lines changed

docs/resources/managed_license.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "gitlab_managed_license Resource - terraform-provider-gitlab"
4+
subcategory: ""
5+
description: |-
6+
This resource allows you to add rules for managing licenses on a project.
7+
For additional information, please see the gitlab documentation https://docs.gitlab.com/ee/user/compliance/license_compliance/.
8+
~> Using this resource requires an active gitlab ultimate https://about.gitlab.com/pricing/subscription.
9+
---
10+
11+
# gitlab_managed_license (Resource)
12+
13+
This resource allows you to add rules for managing licenses on a project.
14+
For additional information, please see the [gitlab documentation](https://docs.gitlab.com/ee/user/compliance/license_compliance/).
15+
16+
~> Using this resource requires an active [gitlab ultimate](https://about.gitlab.com/pricing/)subscription.
17+
18+
## Example Usage
19+
20+
```terraform
21+
resource "gitlab_project" "foo" {
22+
name = "example project"
23+
description = "Lorem Ipsum"
24+
visibility_level = "public"
25+
}
26+
27+
resource "gitlab_managed_license" "mit" {
28+
project = gitlab_project.foo.id
29+
name = "MIT license"
30+
approval_status = "approved"
31+
}
32+
```
33+
34+
<!-- schema generated by tfplugindocs -->
35+
## Schema
36+
37+
### Required
38+
39+
- **approval_status** (String) Whether the license is approved or not. Only 'approved' or 'blacklisted' allowed.
40+
- **name** (String) The name of the managed license (I.e., 'Apache License 2.0' or 'MIT license')
41+
- **project** (String) The ID of the project under which the managed license will be created.
42+
43+
### Optional
44+
45+
- **id** (String) The ID of this resource.
46+
47+
## Import
48+
49+
Import is supported using the following syntax:
50+
51+
```shell
52+
# You can import this resource with an id made up of `{project-id}:{license-id}`, e.g.
53+
terraform import gitlab_managed_license.foo 1:2
54+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# You can import this resource with an id made up of `{project-id}:{license-id}`, e.g.
2+
terraform import gitlab_managed_license.foo 1:2
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
resource "gitlab_project" "foo" {
2+
name = "example project"
3+
description = "Lorem Ipsum"
4+
visibility_level = "public"
5+
}
6+
7+
resource "gitlab_managed_license" "mit" {
8+
project = gitlab_project.foo.id
9+
name = "MIT license"
10+
approval_status = "approved"
11+
}

gitlab/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func Provider() *schema.Provider {
7676
"gitlab_project": resourceGitlabProject(),
7777
"gitlab_project_custom_attribute": resourceGitlabProjectCustomAttribute(),
7878
"gitlab_label": resourceGitlabLabel(),
79+
"gitlab_managed_license": resourceGitlabManagedLicense(),
7980
"gitlab_group_label": resourceGitlabGroupLabel(),
8081
"gitlab_pipeline_schedule": resourceGitlabPipelineSchedule(),
8182
"gitlab_pipeline_schedule_variable": resourceGitlabPipelineScheduleVariable(),
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package gitlab
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
9+
"github.com/xanzy/go-gitlab"
10+
"log"
11+
"strconv"
12+
)
13+
14+
func resourceGitlabManagedLicense() *schema.Resource {
15+
return &schema.Resource{
16+
Description: "This resource allows you to add rules for managing licenses on a project.\n" +
17+
"For additional information, please see the " +
18+
"[gitlab documentation](https://docs.gitlab.com/ee/user/compliance/license_compliance/).\n\n" +
19+
"~> Using this resource requires an active [gitlab ultimate](https://about.gitlab.com/pricing/)" +
20+
"subscription.",
21+
22+
CreateContext: resourceGitlabManagedLicenseCreate,
23+
ReadContext: resourceGitlabManagedLicenseRead,
24+
UpdateContext: resourceGitlabManagedLicenseUpdate,
25+
DeleteContext: resourceGitlabManagedLicenseDelete,
26+
Importer: &schema.ResourceImporter{
27+
StateContext: schema.ImportStatePassthroughContext,
28+
},
29+
30+
Schema: map[string]*schema.Schema{
31+
"project": {
32+
Type: schema.TypeString,
33+
Required: true,
34+
ForceNew: true,
35+
Description: "The ID of the project under which the managed license will be created.",
36+
},
37+
"name": {
38+
Type: schema.TypeString,
39+
Required: true,
40+
// GitLab's edit API doesn't allow us to edit the name, only
41+
// the approval status.
42+
ForceNew: true,
43+
Description: "The name of the managed license (I.e., 'Apache License 2.0' or 'MIT license')",
44+
},
45+
"approval_status": {
46+
Type: schema.TypeString,
47+
Required: true,
48+
ForceNew: false,
49+
ValidateFunc: validation.StringInSlice([]string{"approved", "blacklisted"}, true),
50+
Description: "Whether the license is approved or not. Only 'approved' or 'blacklisted' allowed.",
51+
},
52+
},
53+
}
54+
}
55+
56+
func resourceGitlabManagedLicenseCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
57+
client := meta.(*gitlab.Client)
58+
project := d.Get("project").(string)
59+
60+
options := &gitlab.AddManagedLicenseOptions{
61+
Name: gitlab.String(d.Get("name").(string)),
62+
ApprovalStatus: stringToApprovalStatus(d.Get("approval_status").(string)),
63+
}
64+
65+
log.Printf("[DEBUG] create gitlab Managed License on Project %s, with Name %s", project, *options.Name)
66+
67+
addManagedLicense, _, err := client.ManagedLicenses.AddManagedLicense(project, options, gitlab.WithContext(ctx))
68+
if err != nil {
69+
return diag.FromErr(err)
70+
}
71+
72+
licenseId := strconv.Itoa(addManagedLicense.ID)
73+
d.SetId(buildTwoPartID(&project, &licenseId))
74+
75+
return resourceGitlabManagedLicenseRead(ctx, d, meta)
76+
}
77+
78+
func resourceGitlabManagedLicenseDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
79+
client := meta.(*gitlab.Client)
80+
project, licenseId, err := projectIdAndLicenseIdFromId(d.Id())
81+
if err != nil {
82+
return diag.FromErr(err)
83+
}
84+
85+
log.Printf("[DEBUG] Delete gitlab Managed License %s", d.Id())
86+
_, err = client.ManagedLicenses.DeleteManagedLicense(project, licenseId, gitlab.WithContext(ctx))
87+
if err != nil {
88+
return diag.FromErr(fmt.Errorf("failed to delete managed license %d for projec %s: %w", licenseId, project, err))
89+
}
90+
91+
return nil
92+
}
93+
94+
func resourceGitlabManagedLicenseRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
95+
client := meta.(*gitlab.Client)
96+
project, licenseId, err := projectIdAndLicenseIdFromId(d.Id())
97+
if err != nil {
98+
diag.FromErr(err)
99+
}
100+
101+
log.Printf("[DEBUG] read gitlab Managed License for project/licenseId %s/%d", project, licenseId)
102+
license, _, err := client.ManagedLicenses.GetManagedLicense(project, licenseId, gitlab.WithContext(ctx))
103+
if err != nil {
104+
if is404(err) {
105+
log.Printf("[DEBUG] Managed License %s:%d no longer exists and is being removed from state", project, licenseId)
106+
d.SetId("")
107+
return nil
108+
}
109+
return diag.FromErr(err)
110+
}
111+
112+
d.Set("project", project)
113+
d.Set("name", license.Name)
114+
d.Set("approval_status", license.ApprovalStatus)
115+
116+
return nil
117+
}
118+
119+
func resourceGitlabManagedLicenseUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
120+
client := meta.(*gitlab.Client)
121+
project, licenseId, err := projectIdAndLicenseIdFromId(d.Id())
122+
if err != nil {
123+
return diag.FromErr(err)
124+
}
125+
126+
opts := &gitlab.EditManagedLicenceOptions{
127+
ApprovalStatus: stringToApprovalStatus(d.Get("approval_status").(string)),
128+
}
129+
130+
if d.HasChange("approval_status") {
131+
opts.ApprovalStatus = stringToApprovalStatus(d.Get("approval_status").(string))
132+
}
133+
134+
log.Printf("[DEBUG] update gitlab Managed License %s", d.Id())
135+
_, _, err = client.ManagedLicenses.EditManagedLicense(project, licenseId, opts, gitlab.WithContext(ctx))
136+
if err != nil {
137+
return diag.FromErr(err)
138+
}
139+
140+
licenseIdStr := strconv.Itoa(licenseId)
141+
d.SetId(buildTwoPartID(&project, &licenseIdStr))
142+
143+
return resourceGitlabManagedLicenseRead(ctx, d, meta)
144+
}
145+
146+
// Convert the incoming string into the proper constant value for passing into the API.
147+
func stringToApprovalStatus(s string) *gitlab.LicenseApprovalStatusValue {
148+
lookup := map[string]gitlab.LicenseApprovalStatusValue{
149+
"approved": gitlab.LicenseApproved,
150+
"blacklisted": gitlab.LicenseBlacklisted,
151+
}
152+
153+
value, ok := lookup[s]
154+
if !ok {
155+
return nil
156+
}
157+
return &value
158+
}
159+
160+
func projectIdAndLicenseIdFromId(id string) (string, int, error) {
161+
projectId, id, err := parseTwoPartID(id)
162+
if err != nil {
163+
return "", 0, err
164+
}
165+
166+
licenseId, err := strconv.Atoi(id)
167+
if err != nil {
168+
return "", 0, err
169+
}
170+
171+
return projectId, licenseId, nil
172+
}

0 commit comments

Comments
 (0)