Skip to content

Commit

Permalink
Merge pull request #52 from Infisical/feat/infisical-project-group-re…
Browse files Browse the repository at this point in the history
…source

feat: infiscial-project-group resource
  • Loading branch information
maidul98 authored Sep 24, 2024
2 parents 6662fe3 + 0518fd3 commit ee65bcc
Show file tree
Hide file tree
Showing 12 changed files with 1,072 additions and 0 deletions.
57 changes: 57 additions & 0 deletions docs/data-sources/groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "infisical_groups Data Source - terraform-provider-infisical"
subcategory: ""
description: |-
Interact with Infisical groups in your organization.
---

# infisical_groups (Data Source)

Interact with Infisical groups in your organization.

## Example Usage

```terraform
terraform {
required_providers {
infisical = {
# version = <latest version>
source = "infisical/infisical"
}
}
}
provider "infisical" {
host = "https://app.infisical.com" # Only required if using self hosted instance of Infisical, default is https://app.infisical.com
client_id = "<>"
client_secret = "<>"
}
data "infisical_groups" "groups" {
}
output "org-groups" {
value = data.infisical_groups.groups
}
```

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

### Read-Only

- `groups` (Attributes List) The groups list (see [below for nested schema](#nestedatt--groups))

<a id="nestedatt--groups"></a>
### Nested Schema for `groups`

Read-Only:

- `id` (String) The ID of the group
- `name` (String) The name of the group
- `org_id` (String) The organization ID of the group
- `role` (String) The role of the group in the organization
- `role_id` (String) The role ID of the group in the organization
77 changes: 77 additions & 0 deletions docs/resources/project_group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "infisical_project_group Resource - terraform-provider-infisical"
subcategory: ""
description: |-
Create project groups & save to Infisical. Only Machine Identity authentication is supported for this data source
---

# infisical_project_group (Resource)

Create project groups & save to Infisical. Only Machine Identity authentication is supported for this data source

## Example Usage

```terraform
terraform {
required_providers {
infisical = {
# version = <latest version>
source = "infisical/infisical"
}
}
}
provider "infisical" {
host = "https://app.infisical.com" # Only required if using self hosted instance of Infisical, default is https://app.infisical.com
client_id = "<>"
client_secret = "<>"
}
resource "infisical_project" "example" {
name = "example"
slug = "example"
}
resource "infisical_project_group" "group" {
project_id = infisical_project.example.id
group_slug = "my-group"
roles = [
{
role_slug = "admin",
is_temporary = true,
temporary_access_start_time = "2024-09-19T12:43:13Z",
temporary_range = "1y"
},
{
role_slug = "my-custom-role",
},
]
}
```

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

### Required

- `group_id` (String) The id of the group.
- `project_id` (String) The id of the project.
- `roles` (Attributes Set) The roles assigned to the project group (see [below for nested schema](#nestedatt--roles))

### Read-Only

- `membership_id` (String) The membership Id of the project group

<a id="nestedatt--roles"></a>
### Nested Schema for `roles`

Required:

- `role_slug` (String) The slug of the role

Optional:

- `is_temporary` (Boolean) Flag to indicate the assigned role is temporary or not. When is_temporary is true fields temporary_mode, temporary_range and temporary_access_start_time is required.
- `temporary_access_start_time` (String) ISO time for which temporary access should begin. This is in the format YYYY-MM-DDTHH:MM:SSZ e.g. 2024-09-19T12:43:13Z
- `temporary_range` (String) TTL for the temporary time. Eg: 1m, 1h, 1d. Default: 1h
23 changes: 23 additions & 0 deletions examples/data-sources/infisical_groups/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
terraform {
required_providers {
infisical = {
# version = <latest version>
source = "infisical/infisical"
}
}
}

provider "infisical" {
host = "https://app.infisical.com" # Only required if using self hosted instance of Infisical, default is https://app.infisical.com
client_id = "<>"
client_secret = "<>"
}


data "infisical_groups" "groups" {

}

output "org-groups" {
value = data.infisical_groups.groups
}
35 changes: 35 additions & 0 deletions examples/resources/infisical_project_group/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
terraform {
required_providers {
infisical = {
# version = <latest version>
source = "infisical/infisical"
}
}
}

provider "infisical" {
host = "https://app.infisical.com" # Only required if using self hosted instance of Infisical, default is https://app.infisical.com
client_id = "<>"
client_secret = "<>"
}

resource "infisical_project" "example" {
name = "example"
slug = "example"
}

resource "infisical_project_group" "group" {
project_id = infisical_project.example.id
group_slug = "my-group"
roles = [
{
role_slug = "admin",
is_temporary = true,
temporary_access_start_time = "2024-09-19T12:43:13Z",
temporary_range = "1y"
},
{
role_slug = "my-custom-role",
},
]
}
50 changes: 50 additions & 0 deletions internal/client/group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package infisicalclient

import (
"fmt"
"net/http"
)

func (client Client) GetGroupById(request GetGroupByIdRequest) (Group, error) {
var groupResponse Group
response, err := client.Config.HttpClient.
R().
SetResult(&groupResponse).
SetHeader("User-Agent", USER_AGENT).
Get(fmt.Sprintf("api/v1/groups/%s", request.ID))

if response.StatusCode() == http.StatusNotFound {
return Group{}, ErrNotFound
}

if err != nil {
return Group{}, fmt.Errorf("CallGetGroupById: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return Group{}, fmt.Errorf("CallGetGroupById: Unsuccessful response. [response=%s]", response)
}

return groupResponse, nil
}

func (client Client) GetGroups() (GetGroupsResponse, error) {
var body GetGroupsResponse

httpRequest := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT)

response, err := httpRequest.Get("api/v1/groups")

if err != nil {
return GetGroupsResponse{}, fmt.Errorf("GetGroups: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return GetGroupsResponse{}, fmt.Errorf("GetGroups: Unsuccessful response. [response=%v]", string(response.Body()))
}

return body, nil
}
118 changes: 118 additions & 0 deletions internal/client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ type ProjectWithEnvironments struct {
Environments []ProjectEnvironment `json:"environments"`
}

type GetProjectByIdResponse struct {
Workspace ProjectWithEnvironments `json:"workspace"`
}

type ProjectMemberships struct {
ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Expand Down Expand Up @@ -510,6 +514,10 @@ type GetProjectRequest struct {
Slug string `json:"slug"`
}

type GetProjectByIdRequest struct {
ID string `json:"id"`
}

type UpdateProjectRequest struct {
Slug string `json:"slug"`
ProjectName string `json:"name"`
Expand Down Expand Up @@ -780,6 +788,116 @@ type GetProjectIdentitySpecificPrivilegeResponse struct {
Privilege ProjectIdentitySpecificPrivilege `json:"privilege"`
}

type ProjectGroupRole struct {
ID string `json:"id"`
Role string `json:"role"`
CustomRoleSlug string `json:"customRoleSlug"`
CustomRoleId string `json:"customRoleId"`
IsTemporary bool `json:"isTemporary"`
TemporaryMode string `json:"temporaryMode"`
TemporaryRange string `json:"temporaryRange"`
TemporaryAccessStartTime time.Time `json:"temporaryAccessStartTime"`
TemporaryAccessEndTime time.Time `json:"temporaryAccessEndTime"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}

type ProjectGroup struct {
ID string `json:"id"`
GroupID string `json:"groupId"`
Roles []ProjectGroupRole
}

type CreateProjectGroupRequestRoles struct {
Role string `json:"role"`
IsTemporary bool `json:"isTemporary"`
TemporaryMode string `json:"temporaryMode"`
TemporaryRange string `json:"temporaryRange"`
TemporaryAccessStartTime time.Time `json:"temporaryAccessStartTime"`
}

type CreateProjectGroupRequest struct {
ProjectId string `json:"projectId"`
GroupId string `json:"groupId"`
Roles []CreateProjectGroupRequestRoles `json:"roles"`
}

type CreateProjectGroupResponseMembers struct {
ID string `json:"id"`
GroupID string `json:"groupId"`
}

type CreateProjectGroupResponse struct {
Membership CreateProjectGroupResponseMembers `json:"groupMembership"`
}

type GetProjectGroupMembershipRequest struct {
ProjectId string `json:"projectId"`
GroupId string `json:"groupId"`
}

type GetProjectGroupMembershipResponse struct {
Membership ProjectGroup `json:"groupMembership"`
}

type UpdateProjectGroupRequestRoles struct {
Role string `json:"role"`
IsTemporary bool `json:"isTemporary"`
TemporaryMode string `json:"temporaryMode"`
TemporaryRange string `json:"temporaryRange"`
TemporaryAccessStartTime time.Time `json:"temporaryAccessStartTime"`
}

type UpdateProjectGroupRequest struct {
ProjectId string `json:"projectId"`
GroupId string `json:"groupId"`
Roles []UpdateProjectGroupRequestRoles `json:"roles"`
}

type UpdateProjectGroupResponse struct {
Roles []struct {
ID string `json:"id"`
Role string `json:"role"`
CustomRoleId string `json:"customRoleId"`
IsTemporary bool `json:"isTemporary"`
TemporaryMode string `json:"temporaryMode"`
TemporaryRange string `json:"temporaryRange"`
TemporaryAccessStartTime time.Time `json:"temporaryAccessStartTime"`
TemporaryAccessEndTime time.Time `json:"temporaryAccessEndTime"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
} `json:"roles"`
}

type DeleteProjectGroupRequest struct {
ProjectId string `json:"projectId"`
GroupId string `json:"groupId"`
}

type DeleteProjectGroupResponseMembers struct {
ID string `json:"id"`
GroupID string `json:"groupId"`
}

type DeleteProjectGroupResponse struct {
Membership DeleteProjectGroupResponseMembers `json:"groupMembership"`
}

type GetGroupByIdRequest struct {
ID string `json:"id"`
}

type Group struct {
ID string `json:"id"`
OrgID string `json:"orgId"`
Name string `json:"name"`
Slug string `json:"slug"`
Role string `json:"role"`
RoleId string `json:"roleId"`
}

type GetGroupsResponse []Group

type GetProjectTagsResponse struct {
Tags []ProjectTag `json:"workspaceTags"`
}
Expand Down
Loading

0 comments on commit ee65bcc

Please sign in to comment.