Skip to content

Commit 3fb325f

Browse files
committed
Add Cloud Database Ip Restriction provider
1 parent beeed78 commit 3fb325f

19 files changed

+1179
-77
lines changed

ovh/data_cloud_project_database.go

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package ovh
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/url"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
)
10+
11+
func dataSourceCloudProjectDatabase() *schema.Resource {
12+
return &schema.Resource{
13+
Read: dataSourceCloudProjectDatabaseRead,
14+
Schema: map[string]*schema.Schema{
15+
"service_name": {
16+
Type: schema.TypeString,
17+
Required: true,
18+
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
19+
},
20+
"engine": {
21+
Type: schema.TypeString,
22+
Description: "Name of the engine of the service",
23+
Required: true,
24+
},
25+
"cluster_id": {
26+
Type: schema.TypeString,
27+
Description: "Cluster ID",
28+
Required: true,
29+
},
30+
31+
//Computed
32+
"backup_time": {
33+
Type: schema.TypeString,
34+
Description: "Time on which backups start every day",
35+
Computed: true,
36+
},
37+
"created_at": {
38+
Type: schema.TypeString,
39+
Description: "Date of the creation of the cluster",
40+
Computed: true,
41+
},
42+
"description": {
43+
Type: schema.TypeString,
44+
Description: "Description of the cluster",
45+
Computed: true,
46+
},
47+
"endpoints": {
48+
Type: schema.TypeList,
49+
Description: "List of all endpoints of the service",
50+
Computed: true,
51+
Elem: &schema.Resource{
52+
Schema: map[string]*schema.Schema{
53+
"component": {
54+
Type: schema.TypeString,
55+
Description: "Type of component the URI relates to",
56+
Computed: true,
57+
},
58+
"domain": {
59+
Type: schema.TypeString,
60+
Description: "Domain of the cluster",
61+
Computed: true,
62+
},
63+
"path": {
64+
Type: schema.TypeString,
65+
Description: "Path of the endpoint",
66+
Computed: true,
67+
},
68+
"port": {
69+
Type: schema.TypeInt,
70+
Description: "Connection port for the endpoint",
71+
Computed: true,
72+
},
73+
"scheme": {
74+
Type: schema.TypeString,
75+
Description: "Scheme used to generate the URI",
76+
Computed: true,
77+
},
78+
"ssl": {
79+
Type: schema.TypeBool,
80+
Description: "Defines whether the endpoint uses SSL",
81+
Computed: true,
82+
},
83+
"ssl_mode": {
84+
Type: schema.TypeString,
85+
Description: "SSL mode used to connect to the service if the SSL is enabled",
86+
Computed: true,
87+
},
88+
"uri": {
89+
Type: schema.TypeString,
90+
Description: "URI of the endpoint",
91+
Computed: true,
92+
},
93+
},
94+
},
95+
},
96+
"flavor": {
97+
Type: schema.TypeString,
98+
Description: "The node flavor used for this cluster",
99+
Computed: true,
100+
},
101+
"maintenance_time": {
102+
Type: schema.TypeString,
103+
Description: "Time on which maintenances can start every day",
104+
Computed: true,
105+
},
106+
"network_type": {
107+
Type: schema.TypeString,
108+
Description: "Type of network of the cluster",
109+
Computed: true,
110+
},
111+
"nodes": {
112+
Type: schema.TypeList,
113+
Description: "List of nodes composing the service",
114+
Computed: true,
115+
Elem: &schema.Resource{
116+
Schema: map[string]*schema.Schema{
117+
"network_id": {
118+
Type: schema.TypeString,
119+
Description: "Private network ID in which the node is",
120+
Computed: true,
121+
},
122+
"region": {
123+
Type: schema.TypeString,
124+
Description: "Region of the node",
125+
Computed: true,
126+
},
127+
"subnet_id": {
128+
Type: schema.TypeString,
129+
Description: "Private subnet ID in which the node is",
130+
Computed: true,
131+
},
132+
},
133+
},
134+
},
135+
"plan": {
136+
Type: schema.TypeString,
137+
Description: "Plan of the cluster",
138+
Computed: true,
139+
},
140+
"status": {
141+
Type: schema.TypeString,
142+
Description: "Current status of the cluster",
143+
Computed: true,
144+
},
145+
"version": {
146+
Type: schema.TypeString,
147+
Description: "Version of the engine deployed on the cluster",
148+
Computed: true,
149+
},
150+
},
151+
}
152+
}
153+
154+
func dataSourceCloudProjectDatabaseRead(d *schema.ResourceData, meta interface{}) error {
155+
config := meta.(*Config)
156+
serviceName := d.Get("service_name").(string)
157+
engine := d.Get("engine").(string)
158+
id := d.Get("cluster_id").(string)
159+
160+
serviceEndpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s",
161+
url.PathEscape(serviceName),
162+
url.PathEscape(engine),
163+
url.PathEscape(id),
164+
)
165+
res := &CloudProjectDatabaseResponse{}
166+
167+
log.Printf("[DEBUG] Will read database %s from project: %s", id, serviceName)
168+
if err := config.OVHClient.Get(serviceEndpoint, res); err != nil {
169+
return fmt.Errorf("Error calling GET %s:\n\t %q", serviceEndpoint, err)
170+
}
171+
172+
nodesEndpoint := fmt.Sprintf("%s/node", serviceEndpoint)
173+
nodeList := &[]string{}
174+
if err := config.OVHClient.Get(nodesEndpoint, nodeList); err != nil {
175+
return fmt.Errorf("unable to get database %s nodes: %v", res.Id, err)
176+
}
177+
178+
if len(*nodeList) == 0 {
179+
return fmt.Errorf("no node found for database %s", res.Id)
180+
}
181+
nodeEndpoint := fmt.Sprintf("%s/%s", nodesEndpoint, url.PathEscape((*nodeList)[0]))
182+
node := &CloudProjectDatabaseNodes{}
183+
if err := config.OVHClient.Get(nodeEndpoint, node); err != nil {
184+
return fmt.Errorf("unable to get database %s node %s: %v", res.Id, (*nodeList)[0], err)
185+
}
186+
187+
res.Region = node.Region
188+
189+
for k, v := range res.ToMap() {
190+
if k != "id" {
191+
d.Set(k, v)
192+
} else {
193+
d.SetId(fmt.Sprint(v))
194+
}
195+
}
196+
197+
log.Printf("[DEBUG] Read Database %+v", res)
198+
return nil
199+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package ovh
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/url"
7+
"sort"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
"github.com/ovh/terraform-provider-ovh/ovh/helpers/hashcode"
11+
)
12+
13+
func dataSourceCloudProjectDatabaseIpRestrictions() *schema.Resource {
14+
return &schema.Resource{
15+
Read: dataSourceCloudProjectDatabaseIpRestrictionsRead,
16+
Schema: map[string]*schema.Schema{
17+
"service_name": {
18+
Type: schema.TypeString,
19+
Required: true,
20+
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
21+
},
22+
"engine": {
23+
Type: schema.TypeString,
24+
Description: "Name of the engine of the service",
25+
Required: true,
26+
},
27+
"cluster_id": {
28+
Type: schema.TypeString,
29+
Description: "Cluster ID",
30+
Required: true,
31+
},
32+
33+
//Computed
34+
"ips": {
35+
Type: schema.TypeList,
36+
Description: "List of IP restriction",
37+
Computed: true,
38+
Elem: &schema.Schema{Type: schema.TypeString},
39+
},
40+
},
41+
}
42+
}
43+
44+
func dataSourceCloudProjectDatabaseIpRestrictionsRead(d *schema.ResourceData, meta interface{}) error {
45+
config := meta.(*Config)
46+
serviceName := d.Get("service_name").(string)
47+
engine := d.Get("engine").(string)
48+
clusterId := d.Get("cluster_id").(string)
49+
50+
endpoint := fmt.Sprintf("/cloud/project/%s/database/%s/%s/ipRestriction",
51+
url.PathEscape(serviceName),
52+
url.PathEscape(engine),
53+
url.PathEscape(clusterId),
54+
)
55+
res := make([]string, 0)
56+
57+
log.Printf("[DEBUG] Will read IP restrictions from cluster %s from project %s", clusterId, serviceName)
58+
if err := config.OVHClient.Get(endpoint, &res); err != nil {
59+
return fmt.Errorf("Error calling GET %s:\n\t %q", endpoint, err)
60+
}
61+
62+
// sort.Strings sorts in place, returns nothing
63+
sort.Strings(res)
64+
65+
d.SetId(hashcode.Strings(res))
66+
d.Set("ips", res)
67+
68+
return nil
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package ovh
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
9+
)
10+
11+
const testAccCloudProjectDatabaseIpRestrictionsDatasourceConfig_Basic = `
12+
resource "ovh_cloud_project_database" "db" {
13+
service_name = "%s"
14+
engine = "%s"
15+
version = "%s"
16+
plan = "essential"
17+
nodes {
18+
region = "%s"
19+
}
20+
flavor = "%s"
21+
}
22+
23+
resource "ovh_cloud_project_database_ip_restriction" "ip" {
24+
service_name = ovh_cloud_project_database.db.service_name
25+
engine = ovh_cloud_project_database.db.engine
26+
cluster_id = ovh_cloud_project_database.db.id
27+
ip = "%s"
28+
}
29+
30+
data "ovh_cloud_project_database_ip_restrictions" "ips" {
31+
service_name = ovh_cloud_project_database_ip_restriction.ip.service_name
32+
engine = ovh_cloud_project_database_ip_restriction.ip.engine
33+
cluster_id = ovh_cloud_project_database_ip_restriction.ip.cluster_id
34+
}
35+
`
36+
37+
func TestAccCloudProjectDatabaseIpRestrictionsDataSource_basic(t *testing.T) {
38+
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")
39+
engine := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_ENGINE_TEST")
40+
version := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_VERSION_TEST")
41+
region := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_REGION_TEST")
42+
flavor := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_FLAVOR_TEST")
43+
ip := os.Getenv("OVH_CLOUD_PROJECT_DATABASE_IP_RESTRICTION_IP_TEST")
44+
45+
config := fmt.Sprintf(
46+
testAccCloudProjectDatabaseIpRestrictionsDatasourceConfig_Basic,
47+
serviceName,
48+
engine,
49+
version,
50+
region,
51+
flavor,
52+
ip,
53+
)
54+
55+
resource.Test(t, resource.TestCase{
56+
PreCheck: func() { testAccPreCheckCloudDatabaseIpRestriction(t) },
57+
Providers: testAccProviders,
58+
Steps: []resource.TestStep{
59+
{
60+
Config: config,
61+
Check: resource.ComposeTestCheckFunc(
62+
resource.TestCheckResourceAttrSet(
63+
"data.ovh_cloud_project_database_ip_restrictions.ips",
64+
"ips.#",
65+
),
66+
),
67+
},
68+
},
69+
})
70+
}

0 commit comments

Comments
 (0)