Skip to content

Commit

Permalink
Merge pull request #59 from Infisical/daniel/gcp-integration-support
Browse files Browse the repository at this point in the history
feat: gcp integration support
  • Loading branch information
DanielHougaard authored Oct 3, 2024
2 parents 75a3647 + 0c10ed7 commit 739cccb
Show file tree
Hide file tree
Showing 7 changed files with 761 additions and 0 deletions.
75 changes: 75 additions & 0 deletions docs/resources/integration_gcp_secret_manager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "infisical_integration_gcp_secret_manager Resource - terraform-provider-infisical"
subcategory: ""
description: |-
Create GCP Secret Manager integration & save to Infisical. Only Machine Identity authentication is supported for this data source
---

# infisical_integration_gcp_secret_manager (Resource)

Create GCP Secret Manager integration & 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 = "<machine-identity-client-id>"
client_secret = "<machine-identity-client-secret>"
}
variable "service_account_json" {
type = string
description = "Google Cloud service account JSON key"
}
resource "infisical_integration_gcp_secret_manager" "gcp-integration" {
project_id = "your-project-id"
service_account_json = var.service_account_json
environment = "dev"
secret_path = "/"
gcp_project_id = "gcp-project-id"
}
```

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

### Required

- `environment` (String) The slug of the environment to sync to GCP Secret Manager (prod, dev, staging, etc).
- `gcp_project_id` (String) The ID of the GCP project.
- `project_id` (String) The ID of your Infisical project.
- `secret_path` (String) The secret path in Infisical to sync secrets from.
- `service_account_json` (String, Sensitive) Service account json for the GCP project.

### Optional

- `options` (Attributes) Integration options (see [below for nested schema](#nestedatt--options))

### Read-Only

- `env_id` (String) The ID of the environment, used internally by Infisical.
- `integration_auth_id` (String) The ID of the integration auth, used internally by Infisical.
- `integration_id` (String) The ID of the integration, used internally by Infisical.

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

Optional:

- `secret_prefix` (String) The prefix to add to the secret name in GCP Secret Manager.
- `secret_suffix` (String) The suffix to add to the secret name in GCP Secret Manager.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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 = "<machine-identity-client-id>"
client_secret = "<machine-identity-client-secret>"
}

variable "service_account_json" {
type = string
description = "Google Cloud service account JSON key"
}



resource "infisical_integration_gcp_secret_manager" "gcp-integration" {
project_id = "your-project-id"
service_account_json = var.service_account_json
environment = "dev"
secret_path = "/"
gcp_project_id = "gcp-project-id"

}
68 changes: 68 additions & 0 deletions internal/client/integrations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package infisicalclient

import (
"fmt"
"net/http"
)

func (client Client) CreateIntegration(request CreateIntegrationRequest) (CreateIntegrationResponse, error) {
var body CreateIntegrationResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Post("api/v1/integration")

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

if response.IsError() {
return CreateIntegrationResponse{}, fmt.Errorf("CreateIntegration: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}

func (client Client) GetIntegration(request GetIntegrationRequest) (GetIntegrationResponse, error) {
var body GetIntegrationResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
Get(fmt.Sprintf("api/v1/integration/%s", request.ID))

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

if response.IsError() {
if response.StatusCode() == http.StatusNotFound {
return GetIntegrationResponse{}, ErrNotFound
}
return GetIntegrationResponse{}, fmt.Errorf("CallGetIntegration: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}

func (client Client) UpdateIntegration(request UpdateIntegrationRequest) (UpdateIntegrationResponse, error) {
var body UpdateIntegrationResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Patch(fmt.Sprintf("api/v1/integration/%s", request.ID))

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

if response.IsError() {
return UpdateIntegrationResponse{}, fmt.Errorf("UpdateIntegration: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}
53 changes: 53 additions & 0 deletions internal/client/integrations_auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package infisicalclient

import (
"fmt"
)

// Enum containing the possible values for the `type` field in the CreateIntegrationAuthRequest.
type IntegrationAuthType string

const (
IntegrationAuthTypeGcpSecretManager IntegrationAuthType = "gcp-secret-manager"
)

func (client Client) CreateIntegrationAuth(request CreateIntegrationAuthRequest) (CreateIntegrationAuthResponse, error) {
var body CreateIntegrationAuthResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Post("api/v1/integration-auth/access-token")

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

if response.IsError() {
return CreateIntegrationAuthResponse{}, fmt.Errorf("CreateIntegrationAuth: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}

// Deleting integration auth triggers a cascade effect, that will also delete the associated integration.
func (client Client) DeleteIntegrationAuth(request DeleteIntegrationAuthRequest) (DeleteIntegrationAuthResponse, error) {
var body DeleteIntegrationAuthResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
Delete(fmt.Sprintf("api/v1/integration-auth/%s", request.ID))

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

if response.IsError() {
return DeleteIntegrationAuthResponse{}, fmt.Errorf("DeleteIntegrationAuth: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil

}
112 changes: 112 additions & 0 deletions internal/client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,118 @@ type RevokeIdentityKubernetesAuthResponse struct {
IdentityKubernetesAuth IdentityKubernetesAuth `json:"identityKubernetesAuth"`
}

type CreateIntegrationAuthRequest struct {
RefreshToken string `json:"refreshToken"`
ProjectID string `json:"workspaceId"`
Integration IntegrationAuthType `json:"integration"`
}

type CreateIntegrationAuthResponse struct {
IntegrationAuth struct {
ID string `json:"id"`
} `json:"integrationAuth"`
}

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

type DeleteIntegrationAuthResponse struct {
IntegrationAuth struct {
ID string `json:"id"`
} `json:"integrationAuth"`
}

type IntegrationMetadata struct {
InitialSyncBehavior string `json:"initialSyncBehavior,omitempty"`
SecretPrefix string `json:"secretPrefix"`
SecretSuffix string `json:"secretSuffix"`
MappingBehavior string `json:"mappingBehavior,omitempty"`
ShouldAutoRedeploy bool `json:"shouldAutoRedeploy,omitempty"`
SecretGCPLabel []struct {
LabelName string `json:"labelName,omitempty"`
LabelValue string `json:"labelValue,omitempty"`
} `json:"secretGCPLabel,omitempty"`
SecretAWSTag []struct {
Key string `json:"key,omitempty"`
Value string `json:"value,omitempty"`
} `json:"secretAWSTag,omitempty"`

GithubVisibility string `json:"githubVisibility,omitempty"`
GithubVisibilityRepoIDs []string `json:"githubVisibilityRepoIds,omitempty"`
KMSKeyID string `json:"kmsKeyId,omitempty"`
ShouldDisableDelete bool `json:"shouldDisableDelete,omitempty"`
ShouldEnableDelete bool `json:"shouldEnableDelete,omitempty"`
ShouldMaskSecrets bool `json:"shouldMaskSecrets,omitempty"`
ShouldProtectSecrets bool `json:"shouldProtectSecrets,omitempty"`
}
type CreateIntegrationRequest struct {
IntegrationAuthID string `json:"integrationAuthId"`
App string `json:"app,omitempty"`
AppID string `json:"appId,omitempty"`
SecretPath string `json:"secretPath,omitempty"`
SourceEnvironment string `json:"sourceEnvironment,omitempty"`
TargetEnvironment string `json:"targetEnvironment,omitempty"`
TargetEnvironmentID string `json:"targetEnvironmentId,omitempty"`
TargetService string `json:"targetService,omitempty"`
TargetServiceID string `json:"targetServiceId,omitempty"`
Owner string `json:"owner,omitempty"`
URL string `json:"url,omitempty"`
Path string `json:"path,omitempty"`
Region string `json:"region,omitempty"`
Scope string `json:"scope,omitempty"`

Metadata IntegrationMetadata `json:"metadata,omitempty"`
}

type Integration struct {
ID string `json:"id"`
IsActive bool `json:"isActive"`
URL string `json:"url"`
App string `json:"app"`
AppID string `json:"appId"`
TargetEnvironment string `json:"targetEnvironment"`
TargetEnvironmentID string `json:"targetEnvironmentId"`
TargetService string `json:"targetService"`
TargetServiceID string `json:"targetServiceId"`
Owner string `json:"owner"`
Path string `json:"path"`
Region string `json:"region"`
Scope string `json:"scope"`
Integration string `json:"integration"`
Metadata IntegrationMetadata `json:"metadata,omitempty"`
IntegrationAuthID string `json:"integrationAuthId"`
EnvID string `json:"envId"`
SecretPath string `json:"secretPath"`
}

type CreateIntegrationResponse struct {
Integration Integration `json:"integration"`
}

type GetIntegrationRequest struct {
ID string
}

type GetIntegrationResponse struct {
Integration Integration `json:"integration"`
}

type UpdateIntegrationRequest struct {
ID string
App string `json:"app,omitempty"`
AppID string `json:"appId,omitempty"`
SecretPath string `json:"secretPath,omitempty"`
TargetEnvironment string `json:"targetEnvironment,omitempty"`
Owner string `json:"owner,omitempty"`
Environment string `json:"environment,omitempty"`
Metadata IntegrationMetadata `json:"metadata,omitempty"`
IsActive bool `json:"isActive"`
}

type UpdateIntegrationResponse struct {
Integration Integration `json:"integration"`
}
type SecretApprovalPolicyEnvironment struct {
Slug string `json:"slug"`
}
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ func (p *infisicalProvider) Resources(_ context.Context) []func() resource.Resou
infisicalResource.NewIdentityGcpAuthResource,
infisicalResource.NewIdentityAzureAuthResource,
infisicalResource.NewIdentityOidcAuthResource,
infisicalResource.NewIntegrationGcpSecretManagerResource,
infisicalResource.NewSecretApprovalPolicyResource,
infisicalResource.NewAccessApprovalPolicyResource,
infisicalResource.NewProjectSecretImportResource,
Expand Down
Loading

0 comments on commit 739cccb

Please sign in to comment.