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: create resource to manage oauth2 clients #488

Merged
merged 7 commits into from
Nov 16, 2023
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
77 changes: 77 additions & 0 deletions ovh/data_me_api_oauth2_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package ovh

import (
"context"
"fmt"
"log"
"net/url"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/ovh/terraform-provider-ovh/ovh/helpers"
)

func dataSourceMeApiOauth2Client() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceMeApiOauth2ClientRead,
Schema: map[string]*schema.Schema{
"callback_urls": {
Type: schema.TypeList,
Description: "Callback URLs of the applications using this oauth2 client. Required if using the AUTHORIZATION_CODE flow.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
},
"client_id": {
Type: schema.TypeString,
Description: "Client ID for the oauth2 client, generated during the resource creation.",
Required: true,
},
"description": {
Type: schema.TypeString,
Description: "A description of your oauth2 client.",
Computed: true,
},
"identity": {
Type: schema.TypeString,
Description: "URN that will allow you to associate this oauth2 client with an access policy.",
Computed: true,
},
"flow": {
Type: schema.TypeString,
Description: "OAuth2 flow type implemented for this oauth2 client. Can be either AUTHORIZATION_CODE or CLIENT_CREDENTIALS",
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceMeApiOauth2ClientRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
config := meta.(*Config)

serviceAccount := &ApiOauth2ClientReadResponse{}

// Query the oauth2 client using its client ID
endpoint := fmt.Sprintf("/me/api/oauth2/client/%s", url.PathEscape(d.Get("client_id").(string)))
if err := config.OVHClient.GetWithContext(ctx, endpoint, serviceAccount); err != nil {
return diag.FromErr(helpers.CheckDeleted(d, err, endpoint))
}

log.Printf("[DEBUG] Read oauth2 client: %s", endpoint)

// Populate the state with the response body parameters
d.SetId(serviceAccount.ClientId)
d.Set("callback_urls", serviceAccount.CallbackUrls)
d.Set("client_id", serviceAccount.ClientId)
d.Set("description", serviceAccount.Description)
d.Set("flow", serviceAccount.Flow)
d.Set("identity", serviceAccount.Identity)
d.Set("name", serviceAccount.Name)

return nil
}
45 changes: 45 additions & 0 deletions ovh/data_me_api_oauth2_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ovh

import (
"testing"

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

// Tests valid configurations to create oauth2 clients
func TestAccMeApiOauth2Client_data(t *testing.T) {
const resourceName = "ovh_me_api_oauth2_client.service_account_1"

// Successful test with app required parameters,
// that validates the use of the data instruction
const okConfigClientCredentials = `
resource "ovh_me_api_oauth2_client" "service_account_1" {
description = "tf acc test client credentials"
name = "tf acc test client credentials"
flow = "CLIENT_CREDENTIALS"
}
data "ovh_me_api_oauth2_client" "service_account_1" {
client_id = ovh_me_api_oauth2_client.service_account_1.client_id
depends_on = [ovh_me_api_oauth2_client.service_account_1]
}
output "oauth2_client_name" {
value = data.ovh_me_api_oauth2_client.service_account_1.name
}`
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckCredentials(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
// Create the object, check that the client secret is not empty after creation
{
Config: okConfigClientCredentials,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrWith(resourceName, "client_id", apiOauth2ClientStringNotEmpty),
resource.TestCheckResourceAttrWith(resourceName, "client_secret", apiOauth2ClientStringNotEmpty),
resource.TestCheckOutput(
"oauth2_client_name", "tf acc test client credentials",
),
),
},
},
})
}
39 changes: 39 additions & 0 deletions ovh/data_me_api_oauth2_clients.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ovh

import (
"context"
"sort"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/ovh/terraform-provider-ovh/ovh/helpers/hashcode"
)

func dataSourceMeApiOauth2Clients() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceMeApiOauth2ClientsRead,
Schema: map[string]*schema.Schema{
"client_ids": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
},
}
}

func dataSourceMeApiOauth2ClientsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
config := meta.(*Config)

var oAuth2ClientsIds []string
err := config.OVHClient.GetWithContext(ctx, "/me/api/oauth2/client", &oAuth2ClientsIds)
if err != nil {
return diag.FromErr(err)
}

d.Set("client_ids", oAuth2ClientsIds)

sort.Strings(oAuth2ClientsIds)
d.SetId(hashcode.Strings(oAuth2ClientsIds))
return nil
}
44 changes: 44 additions & 0 deletions ovh/data_me_api_oauth2_clients_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ovh

import (
"testing"

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

// Tests valid configurations to read all oauth2 clients
func TestAccMeApiOauth2Clients_data(t *testing.T) {
// Successful test with app required parameters,
// that validates the use of the data instruction
// We create a resource beforehand, to make sure that at least one service account exists
const okConfigClientCredentials = `
resource "ovh_me_api_oauth2_client" "service_account_1" {
description = "tf acc test client credentials"
name = "tf acc test client credentials"
flow = "CLIENT_CREDENTIALS"
}
# A data source listing all the client ids in the account
data "ovh_me_api_oauth2_clients" "all_clients_ref" {
depends_on = [ovh_me_api_oauth2_client.service_account_1]
}

output "is_array_length_gt_0" {
value = length(data.ovh_me_api_oauth2_clients.all_clients_ref.client_ids) > 0
}
`
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckCredentials(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
// Create the object, check that the client secret is not empty after creation
{
Config: okConfigClientCredentials,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckOutput(
"is_array_length_gt_0", "true",
),
),
},
},
})
}
3 changes: 3 additions & 0 deletions ovh/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ func Provider() *schema.Provider {
"ovh_iploadbalancing_vrack_network": dataSourceIpLoadbalancingVrackNetwork(),
"ovh_iploadbalancing_vrack_networks": dataSourceIpLoadbalancingVrackNetworks(),
"ovh_me": dataSourceMe(),
"ovh_me_api_oauth2_client": dataSourceMeApiOauth2Client(),
"ovh_me_api_oauth2_clients": dataSourceMeApiOauth2Clients(),
"ovh_me_identity_group": dataSourceMeIdentityGroup(),
"ovh_me_identity_groups": dataSourceMeIdentityGroups(),
"ovh_me_identity_user": dataSourceMeIdentityUser(),
Expand Down Expand Up @@ -208,6 +210,7 @@ func Provider() *schema.Provider {
"ovh_iploadbalancing_tcp_route_rule": resourceIPLoadbalancingTcpRouteRule(),
"ovh_iploadbalancing_vrack_network": resourceIPLoadbalancingVrackNetwork(),
"ovh_me_identity_group": resourceMeIdentityGroup(),
"ovh_me_api_oauth2_client": resourceApiOauth2Client(),
"ovh_me_identity_user": resourceMeIdentityUser(),
"ovh_me_installation_template": resourceMeInstallationTemplate(),
"ovh_me_installation_template_partition_scheme": resourceMeInstallationTemplatePartitionScheme(),
Expand Down
Loading