Skip to content

Add page and space data sources #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.2
0.2.3
2 changes: 1 addition & 1 deletion confluence/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func NewClient(input *NewClientInput) *Client {
baseURL.User = url.UserPassword(input.user, input.token)
return &Client{
client: &http.Client{
Timeout: time.Second * 10,
Timeout: time.Second * 30,
},
baseURL: &baseURL,
basePath: basePath,
Expand Down
85 changes: 85 additions & 0 deletions confluence/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,40 @@ type ContentLinks struct {
WebUI string `json:"webui,omitempty"`
}

type Page struct {
Id string `json:"id,omitempty"`
SpaceId string `json:"spaceId,omitempty"`
AuthorId string `json:"authorId,omitempty"`
OwnerId string `json:"ownerId,omitempty"`
ParentId string `json:"parentId,omitempty"`
ParentType string `json:"parentType,omitempty"`
Title string `json:"title,omitempty"`
Version *Version `json:"version,omitempty"`
Body *Body `json:"body,omitempty"`
Links *PageLinks `json:"_links,omitempty"`
}

type PageLinks struct {
EditUI string `json:"editui,omitempty"`
TinyUI string `json:"tinyui,omitempty"`
WebUI string `json:"webui,omitempty"`
}

type PageSearchParams struct {
Id string
SpaceID string
Title string
}

type PageSearchResponse struct {
Results []Page `json:"results,omitempty"`
Links PageSearchResponseLinks `json:"_links,omitempty"`
}

type PageSearchResponseLinks struct {
Next string `json:"next,omitempty"`
}

// SpaceKey is part of Content
type SpaceKey struct {
Key string `json:"key,omitempty"`
Expand Down Expand Up @@ -60,6 +94,57 @@ func (c *Client) GetContent(id string) (*Content, error) {
return &response, nil
}

func (c *Client) GetPage(id string) (*Page, error) {
url := fmt.Sprintf("/api/v2/pages/%s?body-format=storage", id)

var response Page
if err := c.Get(url, &response); err != nil {
return nil, err
}
return &response, nil
}

func (c *Client) SearchPages(searchParams PageSearchParams, includeBody bool) ([]Page, error) {

if searchParams.Id != "" {
response, err := c.GetPage(searchParams.Id)
if err != nil {
return nil, err
}
return []Page{*response}, nil
}

url := "/api/v2/pages?limit=250"
if includeBody {
url += "&body-format=storage"
}
if searchParams.SpaceID != "" {
url += fmt.Sprintf("&space-id=%s", searchParams.SpaceID)
}
if searchParams.Title != "" {
url += fmt.Sprintf("&title=%s", searchParams.Title)
}

var response PageSearchResponse
var result []Page
if err := c.Get(url, &response); err != nil {
return nil, err
}

for i := 0; i < 500; i++ {
result = append(result, response.Results...)
if response.Links.Next == "" {
break
}
// Strip "/wiki" prefix from the provided URL.
nextPageUrl := response.Links.Next[5:len(response.Links.Next)]
if err := c.Get(nextPageUrl, &response); err != nil {
return nil, err
}
}
return result, nil
}

func (c *Client) UpdateContent(content *Content) (*Content, error) {
var response Content
content.Version.Number++
Expand Down
111 changes: 111 additions & 0 deletions confluence/data_source_page.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package confluence

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourcePage() *schema.Resource {
return &schema.Resource{
Read: dataSourcePageRead,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Optional: true,
},
"space_id": {
Type: schema.TypeString,
Optional: true,
},
"title": {
Type: schema.TypeString,
Optional: true,
},
"parent_id": {
Type: schema.TypeString,
Computed: true,
},
"author_id": {
Type: schema.TypeString,
Computed: true,
},
"owner_id": {
Type: schema.TypeString,
Computed: true,
},
"parent_type": {
Type: schema.TypeString,
Computed: true,
},
"body": {
Type: schema.TypeString,
Computed: true,
},
"version": {
Type: schema.TypeInt,
Computed: true,
},
"view_url": {
Type: schema.TypeString,
Computed: true,
},
"edit_url": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourcePageRead(d *schema.ResourceData, m interface{}) error {
client := m.(*Client)
params := PageSearchParams{}
if pageId, ok := d.Get("id").(string); ok {
params.Id = pageId
}
if spaceId, ok := d.Get("space_id").(string); ok {
params.SpaceID = spaceId
}
if title, ok := d.Get("title").(string); ok {
params.Title = title
}

pageResponse, err := client.SearchPages(params, true)
if err != nil {
d.SetId("")
return err
}

pageCount := len(pageResponse)
if pageCount < 1 {
return fmt.Errorf("unable to find page")
}
if pageCount > 1 {
return fmt.Errorf("found multiple pages, provide a unique arguments or use the plural data source")
}

page := pageResponse[0]
d.SetId(page.Id)
pageMap := map[string]interface{}{
"id": page.Id,
"space_id": page.SpaceId,
"title": page.Title,
"parent_id": page.ParentId,
"parent_type": page.ParentType,
"author_id": page.AuthorId,
"owner_id": page.OwnerId,
"body": page.Body.Storage.Value,
"version": page.Version.Number,
"view_url": client.URL(page.Links.WebUI),
"edit_url": client.URL(page.Links.EditUI),
}

for k, v := range pageMap {
err := d.Set(k, v)
if err != nil {
return err
}
}
return nil
}
115 changes: 115 additions & 0 deletions confluence/data_source_pages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package confluence

import (
"fmt"
"hash/crc32"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourcePages() *schema.Resource {
return &schema.Resource{
Read: dataSourcePagesRead,
Schema: map[string]*schema.Schema{
"space_id": {
Type: schema.TypeString,
Optional: true,
},
"title": {
Type: schema.TypeString,
Optional: true,
},
"pages": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"space_id": {
Type: schema.TypeString,
Computed: true,
},
"title": {
Type: schema.TypeString,
Computed: true,
},
"parent_id": {
Type: schema.TypeString,
Computed: true,
},
"author_id": {
Type: schema.TypeString,
Computed: true,
},
"owner_id": {
Type: schema.TypeString,
Computed: true,
},
"parent_type": {
Type: schema.TypeString,
Computed: true,
},
"version": {
Type: schema.TypeInt,
Computed: true,
},
"view_url": {
Type: schema.TypeString,
Computed: true,
},
"edit_url": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

func dataSourcePagesRead(d *schema.ResourceData, m interface{}) error {
client := m.(*Client)
params := PageSearchParams{}
var idStr string
if spaceId, ok := d.Get("space_id").(string); ok {
params.SpaceID = spaceId
idStr += spaceId
}
if title, ok := d.Get("title").(string); ok {
params.Title = title
idStr += title
}

pageResponse, err := client.SearchPages(params, false)
if err != nil {
d.SetId("")
return err
}

pages := make([]map[string]interface{}, len(pageResponse))
for i := range pageResponse {
page := map[string]interface{}{
"id": pageResponse[i].Id,
"space_id": pageResponse[i].SpaceId,
"title": pageResponse[i].Title,
"parent_id": pageResponse[i].ParentId,
"parent_type": pageResponse[i].ParentType,
"author_id": pageResponse[i].AuthorId,
"owner_id": pageResponse[i].OwnerId,
"version": pageResponse[i].Version.Number,
"view_url": client.URL(pageResponse[i].Links.WebUI),
"edit_url": client.URL(pageResponse[i].Links.EditUI),
}

pages[i] = page
}

d.SetId(fmt.Sprintf("%d", crc32.ChecksumIEEE([]byte(idStr))))
_ = d.Set("pages", pages)

return nil
}
Loading