Skip to content

Commit

Permalink
Migrate folder data source to Framework (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
taiidani committed Feb 25, 2024
1 parent 1437c53 commit 8abbec3
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 104 deletions.
36 changes: 23 additions & 13 deletions docs/data-sources/folder.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
# jenkins_folder Data Source
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "jenkins_folder Data Source - terraform-provider-jenkins"
subcategory: ""
description: |-
Get the attributes of a folder within Jenkins.
~> The Jenkins installation that uses this resource is expected to have the Cloudbees Folders Plugin https://plugins.jenkins.io/cloudbees-folder installed in their system.
---

# jenkins_folder (Data Source)

Get the attributes of a folder within Jenkins.

~> The Jenkins installation that uses this resource is expected to have the [Cloudbees Folders Plugin](https://plugins.jenkins.io/cloudbees-folder) installed in their system.

## Example Usage

```hcl
```terraform
data "jenkins_folder" "example" {
name = "folder-name"
name = "folder-name"
}
```

## Argument Reference
<!-- schema generated by tfplugindocs -->
## Schema

The following arguments are supported:
### Required

* `name` - (Required) The name of the folder being read.
* `folder` - (Optional) The folder namespace containing this folder.
- `name` (String) The name of the resource being read.

### Optional

## Attribute Reference
- `folder` (String) The folder namespace containing this resource.

In addition to all arguments above, the following attributes are exported:
### Read-Only

* `id` - The full canonical folder path, E.G. `/job/parent`.
* `description` - A block of text describing the folder's purpose.
* `display_name` - The name of the folder that is displayed in the UI.
* `template` - A Jenkins-compatible XML template to describe the folder.
- `description` (String) The description of this folder's purpose.
- `display_name` (String) The name of the folder to display in the UI.
- `id` (String) The full canonical job path, e.g. `/job/job-name`
- `template` (String) The configuration file template, used to communicate with Jenkins.
3 changes: 3 additions & 0 deletions examples/data-sources/jenkins_folder/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "jenkins_folder" "example" {
name = "folder-name"
}
166 changes: 108 additions & 58 deletions jenkins/data_source_jenkins_folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,122 @@ package jenkins

import (
"context"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

func dataSourceJenkinsFolder() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceJenkinsFolderRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "The unique name of the JenkinsCI folder.",
Required: true,
ValidateDiagFunc: validateJobName,
},
"display_name": {
Type: schema.TypeString,
Description: "The name of the folder to display in the UI.",
Computed: true,
},
"folder": {
Type: schema.TypeString,
Description: "The folder namespace that the folder exists in.",
Optional: true,
ValidateDiagFunc: validateFolderName,
},
"description": {
Type: schema.TypeString,
Description: "The description of this folder's purpose.",
Computed: true,
type folderDataSourceModel struct {
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Folder types.String `tfsdk:"folder"`
Description types.String `tfsdk:"description"`
DisplayName types.String `tfsdk:"display_name"`
Template types.String `tfsdk:"template"`
}

type folderDataSource struct {
*dataSourceHelper
}

// Ensure the implementation satisfies the desired interfaces.
var _ datasource.DataSourceWithConfigure = &folderDataSource{}

func newFolderDataSource() datasource.DataSource {
return &folderDataSource{
dataSourceHelper: newDataSourceHelper(),
}
}

func (d *folderDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_folder"
}

func (d *folderDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: `
Get the attributes of a folder within Jenkins.
~> The Jenkins installation that uses this resource is expected to have the [Cloudbees Folders Plugin](https://plugins.jenkins.io/cloudbees-folder) installed in their system.`,
Attributes: d.schema(map[string]schema.Attribute{
"display_name": schema.StringAttribute{
MarkdownDescription: "The name of the folder to display in the UI.",
Computed: true,
},
"security": {
Type: schema.TypeSet,
Description: "The Jenkins project-based security configuration.",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"inheritance_strategy": {
Type: schema.TypeString,
Description: "The strategy for applying these permissions sets to existing inherited permissions.",
Computed: true,
},
"permissions": {
Type: schema.TypeList,
Computed: true,
Description: "The Jenkins permissions sets that provide access to this folder.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
"description": schema.StringAttribute{
MarkdownDescription: "The description of this folder's purpose.",
Computed: true,
},
"template": {
Type: schema.TypeString,
Description: "The configuration file template, used to communicate with Jenkins.",
Computed: true,
"template": schema.StringAttribute{
MarkdownDescription: "The configuration file template, used to communicate with Jenkins.",
Computed: true,
},
},
}),
}
}

func dataSourceJenkinsFolderRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
name := d.Get("name").(string)
folderName := d.Get("folder").(string)
d.SetId(formatFolderName(folderName + "/" + name))
func (d *folderDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data folderDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

name := data.Name.ValueString()
folderName := data.Folder.ValueString()
name, folders := parseCanonicalJobID(formatFolderName(folderName + "/" + name))
job, err := d.client.GetJob(ctx, name, folders...)
if err != nil {
if strings.HasPrefix(err.Error(), "404") {
// Job does not exist
resp.State.RemoveResource(ctx)
return
}

resp.Diagnostics.AddError(
"Unable to Read Data Source",
"An unexpected error occurred while parsing the data source read response. "+
"Please report this issue to the provider developers.\n\n"+
"Error: "+err.Error(),
)
return
}

// Extract the raw XML configuration
config, err := job.GetConfig(ctx)
if err != nil {
resp.Diagnostics.AddError(
"Unable to Read Data Source",
"An unexpected error occurred while extracting the job configuration. "+
"Please report this issue to the provider developers.\n\n"+
"Error: "+err.Error(),
)
return
}

// Next, parse the properties from the config
f, err := parseFolder(config)
if err != nil {
resp.Diagnostics.AddError(
"Unable to Read Folder",
"An unexpected error occurred while parsing the folder configuration. "+
"Please report this issue to the provider developers.\n\n"+
"Error: "+err.Error(),
)
return
}

data.ID = types.StringValue(job.Base)
data.Name = types.StringValue(name)
data.DisplayName = types.StringValue(f.DisplayName)
data.Folder = types.StringValue(formatFolderID(folders))
data.Description = types.StringValue(f.Description)
data.Template = types.StringValue(strings.TrimSpace(config))

return resourceJenkinsFolderRead(ctx, d, meta)
// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
4 changes: 1 addition & 3 deletions jenkins/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ func Provider() *schema.Provider {
},
},

DataSourcesMap: map[string]*schema.Resource{
"jenkins_folder": dataSourceJenkinsFolder(),
},
DataSourcesMap: map[string]*schema.Resource{},

ResourcesMap: map[string]*schema.Resource{
"jenkins_folder": resourceJenkinsFolder(),
Expand Down
1 change: 1 addition & 0 deletions jenkins/provider_framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func (p *JenkinsProvider) DataSources(ctx context.Context) []func() datasource.D
newCredentialVaultAppRoleDataSource,
newViewDataSource,
newJobDataSource,
newFolderDataSource,
}
}

Expand Down
30 changes: 0 additions & 30 deletions templates/data-sources/folder.md.tmpl

This file was deleted.

0 comments on commit 8abbec3

Please sign in to comment.