Skip to content
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

feat: gcp integration support #59

Merged
merged 8 commits into from
Oct 3, 2024
Merged
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
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 @@
---
DanielHougaard marked this conversation as resolved.
Show resolved Hide resolved
# 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
Loading