Skip to content

Commit

Permalink
Merge pull request #276 from lpatte/PUD-1388_manage-ip-restriction
Browse files Browse the repository at this point in the history
Add Cloud Database IP Restriction provider
  • Loading branch information
scraly authored Jul 27, 2022
2 parents c502a17 + 3fb325f commit ae42e65
Show file tree
Hide file tree
Showing 19 changed files with 1,179 additions and 77 deletions.
199 changes: 199 additions & 0 deletions ovh/data_cloud_project_database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
package ovh

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

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

func dataSourceCloudProjectDatabase() *schema.Resource {
return &schema.Resource{
Read: dataSourceCloudProjectDatabaseRead,
Schema: map[string]*schema.Schema{
"service_name": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
},
"engine": {
Type: schema.TypeString,
Description: "Name of the engine of the service",
Required: true,
},
"cluster_id": {
Type: schema.TypeString,
Description: "Cluster ID",
Required: true,
},

//Computed
"backup_time": {
Type: schema.TypeString,
Description: "Time on which backups start every day",
Computed: true,
},
"created_at": {
Type: schema.TypeString,
Description: "Date of the creation of the cluster",
Computed: true,
},
"description": {
Type: schema.TypeString,
Description: "Description of the cluster",
Computed: true,
},
"endpoints": {
Type: schema.TypeList,
Description: "List of all endpoints of the service",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"component": {
Type: schema.TypeString,
Description: "Type of component the URI relates to",
Computed: true,
},
"domain": {
Type: schema.TypeString,
Description: "Domain of the cluster",
Computed: true,
},
"path": {
Type: schema.TypeString,
Description: "Path of the endpoint",
Computed: true,
},
"port": {
Type: schema.TypeInt,
Description: "Connection port for the endpoint",
Computed: true,
},
"scheme": {
Type: schema.TypeString,
Description: "Scheme used to generate the URI",
Computed: true,
},
"ssl": {
Type: schema.TypeBool,
Description: "Defines whether the endpoint uses SSL",
Computed: true,
},
"ssl_mode": {
Type: schema.TypeString,
Description: "SSL mode used to connect to the service if the SSL is enabled",
Computed: true,
},
"uri": {
Type: schema.TypeString,
Description: "URI of the endpoint",
Computed: true,
},
},
},
},
"flavor": {
Type: schema.TypeString,
Description: "The node flavor used for this cluster",
Computed: true,
},
"maintenance_time": {
Type: schema.TypeString,
Description: "Time on which maintenances can start every day",
Computed: true,
},
"network_type": {
Type: schema.TypeString,
Description: "Type of network of the cluster",
Computed: true,
},
"nodes": {
Type: schema.TypeList,
Description: "List of nodes composing the service",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"network_id": {
Type: schema.TypeString,
Description: "Private network ID in which the node is",
Computed: true,
},
"region": {
Type: schema.TypeString,
Description: "Region of the node",
Computed: true,
},
"subnet_id": {
Type: schema.TypeString,
Description: "Private subnet ID in which the node is",
Computed: true,
},
},
},
},
"plan": {
Type: schema.TypeString,
Description: "Plan of the cluster",
Computed: true,
},
"status": {
Type: schema.TypeString,
Description: "Current status of the cluster",
Computed: true,
},
"version": {
Type: schema.TypeString,
Description: "Version of the engine deployed on the cluster",
Computed: true,
},
},
}
}

func dataSourceCloudProjectDatabaseRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
serviceName := d.Get("service_name").(string)
engine := d.Get("engine").(string)
id := d.Get("cluster_id").(string)

serviceEndpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s",
url.PathEscape(serviceName),
url.PathEscape(engine),
url.PathEscape(id),
)
res := &CloudProjectDatabaseResponse{}

log.Printf("[DEBUG] Will read database %s from project: %s", id, serviceName)
if err := config.OVHClient.Get(serviceEndpoint, res); err != nil {
return fmt.Errorf("Error calling GET %s:\n\t %q", serviceEndpoint, err)
}

nodesEndpoint := fmt.Sprintf("%s/node", serviceEndpoint)
nodeList := &[]string{}
if err := config.OVHClient.Get(nodesEndpoint, nodeList); err != nil {
return fmt.Errorf("unable to get database %s nodes: %v", res.Id, err)
}

if len(*nodeList) == 0 {
return fmt.Errorf("no node found for database %s", res.Id)
}
nodeEndpoint := fmt.Sprintf("%s/%s", nodesEndpoint, url.PathEscape((*nodeList)[0]))
node := &CloudProjectDatabaseNodes{}
if err := config.OVHClient.Get(nodeEndpoint, node); err != nil {
return fmt.Errorf("unable to get database %s node %s: %v", res.Id, (*nodeList)[0], err)
}

res.Region = node.Region

for k, v := range res.ToMap() {
if k != "id" {
d.Set(k, v)
} else {
d.SetId(fmt.Sprint(v))
}
}

log.Printf("[DEBUG] Read Database %+v", res)
return nil
}
69 changes: 69 additions & 0 deletions ovh/data_cloud_project_database_ip_restrictions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package ovh

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

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

func dataSourceCloudProjectDatabaseIpRestrictions() *schema.Resource {
return &schema.Resource{
Read: dataSourceCloudProjectDatabaseIpRestrictionsRead,
Schema: map[string]*schema.Schema{
"service_name": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
},
"engine": {
Type: schema.TypeString,
Description: "Name of the engine of the service",
Required: true,
},
"cluster_id": {
Type: schema.TypeString,
Description: "Cluster ID",
Required: true,
},

//Computed
"ips": {
Type: schema.TypeList,
Description: "List of IP restriction",
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

func dataSourceCloudProjectDatabaseIpRestrictionsRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
serviceName := d.Get("service_name").(string)
engine := d.Get("engine").(string)
clusterId := d.Get("cluster_id").(string)

endpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s/ipRestriction",
url.PathEscape(serviceName),
url.PathEscape(engine),
url.PathEscape(clusterId),
)
res := make([]string, 0)

log.Printf("[DEBUG] Will read IP restrictions from cluster %s from project %s", clusterId, serviceName)
if err := config.OVHClient.Get(endpoint, &res); err != nil {
return fmt.Errorf("Error calling GET %s:\n\t %q", endpoint, err)
}

// sort.Strings sorts in place, returns nothing
sort.Strings(res)

d.SetId(hashcode.Strings(res))
d.Set("ips", res)

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

import (
"fmt"
"os"
"testing"

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

const testAccCloudProjectDatabaseIpRestrictionsDatasourceConfig_Basic = `
resource "ovh_cloud_project_database" "db" {
service_name = "%s"
engine = "%s"
version = "%s"
plan = "essential"
nodes {
region = "%s"
}
flavor = "%s"
}
resource "ovh_cloud_project_database_ip_restriction" "ip" {
service_name = ovh_cloud_project_database.db.service_name
engine = ovh_cloud_project_database.db.engine
cluster_id = ovh_cloud_project_database.db.id
ip = "%s"
}
data "ovh_cloud_project_database_ip_restrictions" "ips" {
service_name = ovh_cloud_project_database_ip_restriction.ip.service_name
engine = ovh_cloud_project_database_ip_restriction.ip.engine
cluster_id = ovh_cloud_project_database_ip_restriction.ip.cluster_id
}
`

func TestAccCloudProjectDatabaseIpRestrictionsDataSource_basic(t *testing.T) {
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")
engine := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_ENGINE_TEST")
version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST")
region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST")
flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST")
ip := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_IP_RESTRICTION_IP_TEST")

config := fmt.Sprintf(
testAccCloudProjectDatabaseIpRestrictionsDatasourceConfig_Basic,
serviceName,
engine,
version,
region,
flavor,
ip,
)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckCloudDatabaseIpRestriction(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"data.ovh_cloud_project_database_ip_restrictions.ips",
"ips.#",
),
),
},
},
})
}
Loading

0 comments on commit ae42e65

Please sign in to comment.