diff --git a/.changelog/544.txt b/.changelog/544.txt deleted file mode 100644 index 24f406b07..000000000 --- a/.changelog/544.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -`resource/cloudavenue_backup` - New resource to manage NetBackup feature. -``` \ No newline at end of file diff --git a/.changelog/558.txt b/.changelog/558.txt new file mode 100644 index 000000000..264eed10f --- /dev/null +++ b/.changelog/558.txt @@ -0,0 +1,7 @@ +```release-note:feature +`resource/cloudavenue_backup` - New resource to manage NetBackup feature. +``` + +```release-note:feature +`datasource/cloudavenue_backup` - New datasource to manage NetBackup feature. +``` \ No newline at end of file diff --git a/docs/data-sources/backup.md b/docs/data-sources/backup.md new file mode 100644 index 000000000..b54f4ddf9 --- /dev/null +++ b/docs/data-sources/backup.md @@ -0,0 +1,45 @@ +--- +page_title: "cloudavenue_backup Data Source - cloudavenue" +subcategory: "Backup" +description: |- + The cloudavenue_backup data source allows you to retrieve information about a backup of NetBackup solution. +--- + +# cloudavenue_backup (Data Source) + +The `cloudavenue_backup` data source allows you to retrieve information about a backup of NetBackup solution. + +## Example Usage + +```terraform +data "cloudavenue_backup" "example" { + type = "vdc" + target_name = data.cloudavenue_vdc.example.name +} +``` + + +## Schema + +### Required + +- `type` (String) Scope of the backup. + +### Optional + +- `id` (Number) The ID of the backup. +- `target_id` (String) The ID of the target. A target can be a VDC, a VApp or a VM. +- `target_name` (String) The name of the target. A target can be a VDC, a VApp or a VM. + +### Read-Only + +- `policies` (Attributes Set) The backup policies of the target. (see [below for nested schema](#nestedatt--policies)) + + +### Nested Schema for `policies` + +Read-Only: + +- `policy_id` (Number) The ID of the backup policy. +- `policy_name` (String) The name of the backup policy. + diff --git a/examples/data-sources/cloudavenue_backup/data-source.tf b/examples/data-sources/cloudavenue_backup/data-source.tf new file mode 100644 index 000000000..20de5f199 --- /dev/null +++ b/examples/data-sources/cloudavenue_backup/data-source.tf @@ -0,0 +1,4 @@ +data "cloudavenue_backup" "example" { + type = "vdc" + target_name = data.cloudavenue_vdc.example.name +} \ No newline at end of file diff --git a/go.mod b/go.mod index f0cba1401..558a61dbb 100644 --- a/go.mod +++ b/go.mod @@ -19,12 +19,13 @@ require ( github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 github.com/iancoleman/strcase v0.3.0 + github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.3-0.20231009201953-47ea587cab76 github.com/orange-cloudavenue/infrapi-sdk-go v0.1.4-0.20231005074857-89878ea119fb github.com/orange-cloudavenue/netbackup-sdk-go v0.0.2-0.20230928095122-108fd1ec28ae github.com/rs/zerolog v1.31.0 github.com/thanhpk/randstr v1.0.6 github.com/vmware/go-vcloud-director/v2 v2.21.0 - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df + golang.org/x/exp v0.0.0-20231006140011-7918f672742d golang.org/x/net v0.15.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -48,7 +49,7 @@ require ( github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-chi/render v1.0.3 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect - github.com/go-resty/resty/v2 v2.8.0 // indirect + github.com/go-resty/resty/v2 v2.9.1 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -72,6 +73,7 @@ require ( github.com/imdario/mergo v0.3.15 // indirect github.com/influxdata/influxdb-client-go/v2 v2.12.3 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect + github.com/k0kubun/pp v3.0.1+incompatible // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -88,6 +90,7 @@ require ( github.com/posener/complete v1.2.3 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday v1.6.0 // indirect + github.com/sethvargo/go-envconfig v0.9.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect @@ -95,14 +98,12 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.14.0 // indirect golang.org/x/crypto v0.13.0 // indirect - golang.org/x/mod v0.12.0 // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sys v0.12.0 // indirect + golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect google.golang.org/grpc v1.57.0 // indirect google.golang.org/protobuf v1.31.0 // indirect ) - -replace github.com/orange-cloudavenue/netbackup-sdk-go => /Users/micheneaudavid/go/src/github.com/orange-cloudavenue/netbackup-sdk-go diff --git a/go.sum b/go.sum index 22acc3c7e..7f5d60d5f 100644 --- a/go.sum +++ b/go.sum @@ -80,6 +80,8 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.8.0 h1:J29d0JFWwSWrDCysnOK/YjsPMLQTx0TvgJEHVGvf2L8= github.com/go-resty/resty/v2 v2.8.0/go.mod h1:UCui0cMHekLrSntoMyofdSTaPpinlRHFtPpizuyDW2w= +github.com/go-resty/resty/v2 v2.9.1 h1:PIgGx4VrHvag0juCJ4dDv3MiFRlDmP0vicBucwf+gLM= +github.com/go-resty/resty/v2 v2.9.1/go.mod h1:4/GYJVjh9nhkhGR6AUNW3XhpDYNUr+Uvy9gV/VGZIy4= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -166,6 +168,8 @@ github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7 github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40= +github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -216,8 +220,20 @@ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.1 h1:w8+qI+/ifW2/9vOL5ybwNhfE8wdFTFuQvxPavfvsMv0= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.1/go.mod h1:bMSQ+EQ0CtwIca1J133sM9fc/4cAfLXN3r4TpnS0BDY= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.2-0.20231009102548-20090d27feda h1:2Nx3DwfYUXO8Za60mCU9Y3zUHAeUuBRpItsBuvFo/As= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.2-0.20231009102548-20090d27feda/go.mod h1:2V4Inp7YP1SrYfPWFdoPLDQ3etTIUef1SJzmajEmfAY= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.2-0.20231009152625-5f4de427effc h1:EhAfGdE6BCpfox6ZVLETnzaCXfFNz+d+zJrJbm4jhDI= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.2-0.20231009152625-5f4de427effc/go.mod h1:SWH4rhCBBAGIVjkAPOQ3+HWJyE3t1BlvorfGTExs9Yw= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.3-0.20231009201953-47ea587cab76 h1:wMZjH50aktG4x7/B6LWF49vhdI/0Oj5/aWy6nu5EBHk= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.0.3-0.20231009201953-47ea587cab76/go.mod h1:DWBIS3DJtS5ZiZzblCwYNo123RaxO+UrGyfqsVQbFb0= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.1.3 h1:nnFO5vxf70gWZkPcM153LYwHA1fa+0QqtzH2t71AMFA= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.1.3/go.mod h1:bMSQ+EQ0CtwIca1J133sM9fc/4cAfLXN3r4TpnS0BDY= github.com/orange-cloudavenue/infrapi-sdk-go v0.1.4-0.20231005074857-89878ea119fb h1:1/Wc21Tp9RnDOUTjKBm9x3wi+UgUkDc2bv0fHJc5f2o= github.com/orange-cloudavenue/infrapi-sdk-go v0.1.4-0.20231005074857-89878ea119fb/go.mod h1:pGa9mB6s+weCi5QtNe5nicp7yL0C/e+i+3wHRh4cjBE= +github.com/orange-cloudavenue/netbackup-sdk-go v0.0.2-0.20230928095122-108fd1ec28ae h1:eOxAQKxWiC1iJzhhLW2bD4UCe55viWa0v3IejsbKjdE= +github.com/orange-cloudavenue/netbackup-sdk-go v0.0.2-0.20230928095122-108fd1ec28ae/go.mod h1:KaxPSw6c1JNm+F9YRydHVEhoNjIfrjadKl0BPhRLPvM= github.com/peterhellberg/link v1.2.0 h1:UA5pg3Gp/E0F2WdX7GERiNrPQrM1K6CVJUUWfHa4t6c= github.com/peterhellberg/link v1.2.0/go.mod h1:gYfAh+oJgQu2SrZHg5hROVRQe1ICoK0/HHJTcE0edxc= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= @@ -240,6 +256,8 @@ github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3V github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE= +github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -287,10 +305,14 @@ golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -335,6 +357,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -356,12 +380,14 @@ golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/internal/client/client.go b/internal/client/client.go index 365f628f6..ec330cf6d 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -9,6 +9,7 @@ import ( "github.com/vmware/go-vcloud-director/v2/govcd" + clientca "github.com/orange-cloudavenue/cloudavenue-sdk-go" apiclient "github.com/orange-cloudavenue/infrapi-sdk-go" ) @@ -44,7 +45,9 @@ type CloudAvenue struct { VCDVersion string // API NetBackup - NetBackup *NetBackup + // NetBackup *NetBackup + NetBackupClient *clientca.Client + NetBackupOpts *clientca.ClientOpts } // New creates a new CloudAvenue client. @@ -77,11 +80,15 @@ func (c *CloudAvenue) New() (*CloudAvenue, error) { } // API NetBackup - if c.NetBackup.IsDefined() { - if err := c.NewNetBackupClient(); err != nil { - return nil, err - } + // if c.NetBackup.Netbackup.Endpoint != "" || c.NetBackup.Netbackup.Username != "" || c.NetBackup.Netbackup.Password != "" { + c.NetBackupClient, err = clientca.New(*c.NetBackupOpts) + if err != nil { + return nil, fmt.Errorf("%w : %w", ErrConfigureNetBackup, err) } + // if err := c.NewNetBackupClient(); err != nil { + // return nil, err + // } + // } return c, nil } diff --git a/internal/client/netbackup.go b/internal/client/netbackup.go deleted file mode 100644 index f3751ede1..000000000 --- a/internal/client/netbackup.go +++ /dev/null @@ -1,37 +0,0 @@ -package client - -import ( - "fmt" - - netbackupclient "github.com/orange-cloudavenue/netbackup-sdk-go" -) - -// Netbackup is the main struct for the NetBackup client. -type NetBackup struct { - Client *netbackupclient.Client - URL string - User string - Password string -} - -// NewNetBackup creates a new NetBackup client. -func (c *CloudAvenue) NewNetBackupClient() (err error) { - c.NetBackup.Client, err = netbackupclient.New(netbackupclient.Opts{ - APIEndpoint: c.NetBackup.URL, - Username: c.NetBackup.User, - Password: c.NetBackup.Password, - Debug: false, - }) - if err != nil { - return fmt.Errorf("%w : %w", ErrConfigureNetBackup, err) - } - return -} - -// IsDefined checks if the NetBackup configuration is defined. -func (nB *NetBackup) IsDefined() bool { - if nB.URL != "" || nB.User != "" || nB.Password != "" { - return true - } - return false -} diff --git a/internal/provider/backup/backup_resource.go b/internal/provider/backup/backup_resource.go index 0e9e72b0b..a278f7775 100644 --- a/internal/provider/backup/backup_resource.go +++ b/internal/provider/backup/backup_resource.go @@ -5,13 +5,12 @@ import ( "fmt" "strings" - "github.com/orange-cloudavenue/netbackup-sdk-go/netbackupclient" - "github.com/orange-cloudavenue/netbackup-sdk-go/netbackupclient/common" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" + v1common "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/common/netbackup" + v1 "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/metrics" ) @@ -36,6 +35,7 @@ func NewBackupResource() resource.Resource { // backupResource is the resource implementation. type backupResource struct { client *client.CloudAvenue + // nb *casdk.Client } // Metadata returns the resource type name. @@ -84,6 +84,17 @@ func (r *backupResource) Create(ctx context.Context, req resource.CreateRequest, return } + // Refresh data NetBackup from the API + job, err := r.client.NetBackupClient.V1.Netbackup.Inventory.Refresh() + if err != nil { + resp.Diagnostics.AddError("Error refreshing NetBackup inventory", err.Error()) + return + } + if err := job.Wait(1, 45); err != nil { + resp.Diagnostics.AddError("Error waiting for NetBackup inventory refresh", err.Error()) + return + } + // Get the type target object typeTarget, d := r.getTarget(plan) if d.HasError() { @@ -281,6 +292,17 @@ func (r *backupResource) ImportState(ctx context.Context, req resource.ImportSta return } + // Refresh data NetBackup from the API + job, err := r.client.NetBackupClient.V1.Netbackup.Inventory.Refresh() + if err != nil { + resp.Diagnostics.AddError("Error refreshing NetBackup inventory", err.Error()) + return + } + if err := job.Wait(1, 15); err != nil { + resp.Diagnostics.AddError("Error waiting for NetBackup inventory refresh", err.Error()) + return + } + data := NewBackup() data.Type.Set(idParts[0]) data.TargetName.Set(idParts[1]) @@ -299,11 +321,11 @@ func (r *backupResource) ImportState(ctx context.Context, req resource.ImportSta // * CustomFuncs type target interface { - GetProtectionLevelAvailableByName(string) (*netbackupclient.ProtectionLevel, error) - Protect(netbackupclient.ProtectUnprotectRequest) (*common.JobAPIResponse, error) - Unprotect(netbackupclient.ProtectUnprotectRequest) (*common.JobAPIResponse, error) + GetProtectionLevelAvailableByName(string) (*v1.ProtectionLevel, error) + Protect(v1.ProtectUnprotectRequest) (*v1common.JobAPIResponse, error) + Unprotect(v1.ProtectUnprotectRequest) (*v1common.JobAPIResponse, error) GetID() int - ListProtectionLevels() (*netbackupclient.ProtectionLevels, error) + ListProtectionLevels() (*v1.ProtectionLevels, error) } // Apply the protection level for a policy to the target. @@ -311,11 +333,11 @@ type target interface { // Return a policy with the protection level ID. // Return an error if any. func applyPolicy[T target](t T, policy backupModelPolicy) (backupModelPolicy, error) { - var job *common.JobAPIResponse + var job *v1common.JobAPIResponse var err error // apply the protection levels - job, err = t.Protect(netbackupclient.ProtectUnprotectRequest{ + job, err = t.Protect(v1.ProtectUnprotectRequest{ ProtectionLevelID: policy.PolicyID.GetIntPtr(), ProtectionLevelName: policy.PolicyName.Get(), }) @@ -369,7 +391,7 @@ func unApplyPolicies[T target](t T, policies *backupModelPolicies) (err error) { // Return an error if any. func unApplyPolicy[T target](t T, policy backupModelPolicy) error { // apply the protection levels - job, err := t.Unprotect(netbackupclient.ProtectUnprotectRequest{ + job, err := t.Unprotect(v1.ProtectUnprotectRequest{ ProtectionLevelID: policy.PolicyID.GetIntPtr(), ProtectionLevelName: policy.PolicyName.Get(), }) @@ -387,7 +409,7 @@ func unApplyPolicy[T target](t T, policy backupModelPolicy) error { func (r *backupResource) read(ctx context.Context, planOrState *backupModel) (stateRefreshed *backupModel, found bool, diags diag.Diagnostics) { stateRefreshed = planOrState.Copy() - var policiesFromAPI *netbackupclient.ProtectionLevels + var policiesFromAPI *v1.ProtectionLevels // *netbackupclient.ProtectionLevels // Get the type target object typeTarget, d := r.getTarget(planOrState) @@ -433,11 +455,11 @@ func (r *backupResource) getTarget(data *backupModel) (typeTarget target, d diag var err error switch data.Type.Get() { case vdc: - typeTarget, err = r.client.NetBackup.Client.VCloud.GetVdcByNameOrIdentifier(data.getTargetIDOrName()) + typeTarget, err = r.client.NetBackupClient.V1.Netbackup.VCloud.GetVdcByNameOrIdentifier(data.getTargetIDOrName()) case vapp: - typeTarget, err = r.client.NetBackup.Client.VCloud.GetVAppByNameOrIdentifier(data.getTargetIDOrName()) + typeTarget, err = r.client.NetBackupClient.V1.Netbackup.VCloud.GetVAppByNameOrIdentifier(data.getTargetIDOrName()) case vm: - typeTarget, err = r.client.NetBackup.Client.Machines.GetMachineByNameOrIdentifier(data.getTargetIDOrName()) + typeTarget, err = r.client.NetBackupClient.V1.Netbackup.Machines.GetMachineByNameOrIdentifier(data.getTargetIDOrName()) } if err != nil { d.AddError(fmt.Sprintf("Error getting vCloud Director %s", data.Type.Get()), err.Error()) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index c63e1cc50..c99eee8dc 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -10,6 +10,10 @@ import ( "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + casdk "github.com/orange-cloudavenue/cloudavenue-sdk-go" + clientcloudavenue "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/clients/cloudavenue" + clientnetbackup "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/clients/netbackup" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client" ) @@ -54,6 +58,12 @@ func (p *cloudavenueProvider) Configure(ctx context.Context, req provider.Config return } + netbackup := clientnetbackup.Opts{ + Endpoint: findValue(config.NetBackupURL, "NETBACKUP_URL"), + Username: findValue(config.NetBackupUser, "NETBACKUP_USER"), + Password: findValue(config.NetBackupPassword, "NETBACKUP_PASSWORD"), + } + cloudAvenue := client.CloudAvenue{ URL: func() string { url := findValue(config.URL, "CLOUDAVENUE_URL") @@ -69,11 +79,7 @@ func (p *cloudavenueProvider) Configure(ctx context.Context, req provider.Config TerraformVersion: req.TerraformVersion, CloudAvenueVersion: p.version, VCDVersion: VCDVersion, - NetBackup: &client.NetBackup{ - URL: findValue(config.NetBackupURL, "NETBACKUP_URL"), - User: findValue(config.NetBackupUser, "NETBACKUP_USER"), - Password: findValue(config.NetBackupPassword, "NETBACKUP_PASSWORD"), - }, + NetBackupOpts: &casdk.ClientOpts{Netbackup: netbackup, CloudAvenue: clientcloudavenue.Opts{}}, } // If any of the expected configurations are missing, return @@ -106,30 +112,30 @@ func (p *cloudavenueProvider) Configure(ctx context.Context, req provider.Config ) } - if cloudAvenue.NetBackup.IsDefined() { - // Default URL to the public NetBackup API if not set. - if cloudAvenue.NetBackup.URL == "" { - cloudAvenue.NetBackup.URL = "https://backup1.cloudavenue.orange-business.com/NetBackupSelfServiceNetBackupPanels/Api" - } - if cloudAvenue.NetBackup.User == "" { - resp.Diagnostics.AddAttributeError( - path.Root("netbackup_user"), - "Missing NetBackup API User", - "The provider cannot create the NetBackup API client as there is a missing or empty value for the NetBackup API user. "+ - "Set the host value in the configuration or use the NETBACKUP_USER environment variable. "+ - "If either is already set, ensure the value is not empty.", - ) - } - if cloudAvenue.NetBackup.Password == "" { - resp.Diagnostics.AddAttributeError( - path.Root("netbackup_password"), - "Missing NetBackup API Password", - "The provider cannot create the NetBackup API client as there is a missing or empty value for the NetBackup API password. "+ - "Set the host value in the configuration or use the NETBACKUP_PASSWORD environment variable. "+ - "If either is already set, ensure the value is not empty.", - ) - } - } + // if cloudAvenue.NetBackupOpts.IsDefined() { + // // Default URL to the public NetBackup API if not set. + // if cloudAvenue.NetBackupOpts.URL == "" { + // cloudAvenue.NetBackupOpts.URL = "https://backup1.cloudavenue.orange-business.com/NetBackupSelfServiceNetBackupPanels/Api" + // } + // if cloudAvenue.NetBackup.User == "" { + // resp.Diagnostics.AddAttributeError( + // path.Root("netbackup_user"), + // "Missing NetBackup API User", + // "The provider cannot create the NetBackup API client as there is a missing or empty value for the NetBackup API user. "+ + // "Set the host value in the configuration or use the NETBACKUP_USER environment variable. "+ + // "If either is already set, ensure the value is not empty.", + // ) + // } + // if cloudAvenue.NetBackup.Password == "" { + // resp.Diagnostics.AddAttributeError( + // path.Root("netbackup_password"), + // "Missing NetBackup API Password", + // "The provider cannot create the NetBackup API client as there is a missing or empty value for the NetBackup API password. "+ + // "Set the host value in the configuration or use the NETBACKUP_PASSWORD environment variable. "+ + // "If either is already set, ensure the value is not empty.", + // ) + // } + // } if resp.Diagnostics.HasError() { return } diff --git a/internal/testsacc/backup_resource_test.go b/internal/testsacc/backup_resource_test.go index 86d85448b..88243d6a2 100644 --- a/internal/testsacc/backup_resource_test.go +++ b/internal/testsacc/backup_resource_test.go @@ -31,7 +31,7 @@ func (r *BackupResource) GetResourceName() string { func (r *BackupResource) DependenciesConfig() (configs testsacc.TFData) { // TODO : Add dependencies config configs.Append(GetResourceConfig()[VDCResourceName]().GetDefaultConfig()) - // configs.Append(GetResourceConfig()[VAPPResourceName]().GetDefaultConfig()) + configs.Append(GetResourceConfig()[VAppResourceName]().GetDefaultConfig()) // configs.Append(GetResourceConfig()[VMResourceName]().GetDefaultConfig()) return } @@ -41,20 +41,21 @@ func (r *BackupResource) Tests(ctx context.Context) map[testsacc.TestName]func(c // TODO : Complete tests // * First Test For a VDC Backup named "example" "example": func(_ context.Context, resourceName string) testsacc.Test { + // tflog.Info(ctx, pp.Sprintf("GetAllValuesFromTemplate: %v", testsacc.GetAllValuesFromTemplate())) return testsacc.Test{ CommonChecks: []resource.TestCheckFunc{ resource.TestCheckResourceAttrSet(resourceName, "id"), - resource.TestCheckResourceAttr(resourceName, "target_name", "example"), + resource.TestCheckResourceAttrSet(resourceName, "target_name"), }, // ! Create testing Create: testsacc.TFConfig{ TFConfig: ` resource "cloudavenue_backup" "example" { - type = "vdc" - target_name = cloudavenue_vdc.example.name - policies = [{ - policy_name = "D6" - }] + type = "vdc" + target_name = cloudavenue_vdc.example.name + policies = [{ + policy_name = "D6" + }] }`, Checks: []resource.TestCheckFunc{ resource.TestCheckResourceAttr(resourceName, "type", "vdc"), @@ -66,14 +67,14 @@ func (r *BackupResource) Tests(ctx context.Context) map[testsacc.TestName]func(c { TFConfig: ` resource "cloudavenue_backup" "example" { - type = "vdc" - target_name = cloudavenue_vdc.example.name - policies = [{ - policy_name = "D6" - }, - { - policy_name = "D30" - }] + type = "vdc" + target_name = cloudavenue_vdc.example.name + policies = [{ + policy_name = "D6" + },{ + policy_name = "D30" + } + ] }`, Checks: []resource.TestCheckFunc{ resource.TestCheckResourceAttr(resourceName, "policies.0.policy_name", "D6"), @@ -96,7 +97,7 @@ func (r *BackupResource) Tests(ctx context.Context) map[testsacc.TestName]func(c return testsacc.Test{ CommonChecks: []resource.TestCheckFunc{ resource.TestCheckResourceAttrSet(resourceName, "id"), - resource.TestCheckResourceAttr(resourceName, "target_name", "example"), + resource.TestCheckResourceAttrSet(resourceName, "target_name"), }, // ! Create testing Create: testsacc.TFConfig{ @@ -143,58 +144,58 @@ func (r *BackupResource) Tests(ctx context.Context) map[testsacc.TestName]func(c }, } }, - // * Second Test For a VM Backup named "example" - "example3": func(_ context.Context, resourceName string) testsacc.Test { - return testsacc.Test{ - CommonChecks: []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet(resourceName, "id"), - resource.TestCheckResourceAttr(resourceName, "target_name", "example"), - }, - // ! Create testing - Create: testsacc.TFConfig{ - TFConfig: ` - resource "cloudavenue_backup" "example" { - type = "vm" - target_name = cloudavenue_vm.example.name - policies = [{ - policy_name = "D6" - }] - }`, - Checks: []resource.TestCheckFunc{ - resource.TestCheckResourceAttr(resourceName, "type", "vm"), - resource.TestCheckResourceAttr(resourceName, "policies.0.policy_name", "D6"), - }, - }, - // ! Updates testing - Updates: []testsacc.TFConfig{ - { - TFConfig: ` - resource "cloudavenue_backup" "example" { - type = "vm" - target_name = cloudavenue_vm.example.name - policies = [{ - policy_name = "D6" - }, - { - policy_name = "D30" - }] - }`, - Checks: []resource.TestCheckFunc{ - resource.TestCheckResourceAttr(resourceName, "policies.0.policy_name", "D6"), - resource.TestCheckResourceAttr(resourceName, "policies.1.policy_name", "D30"), - }, - }, - }, - // ! Imports testing - Imports: []testsacc.TFImport{ - { - ImportStateIDFunc: testAccBackupResourceImportStateIDFuncWithTypeAndTargetName(resourceName), - ImportState: true, - ImportStateVerify: true, - }, - }, - } - }, + // // * Second Test For a VM Backup named "example" + // "example3": func(_ context.Context, resourceName string) testsacc.Test { + // return testsacc.Test{ + // CommonChecks: []resource.TestCheckFunc{ + // resource.TestCheckResourceAttrSet(resourceName, "id"), + // resource.TestCheckResourceAttrSet(resourceName, "target_name"), + // }, + // // ! Create testing + // Create: testsacc.TFConfig{ + // TFConfig: ` + // resource "cloudavenue_backup" "example" { + // type = "vm" + // target_name = cloudavenue_vm.example.name + // policies = [{ + // policy_name = "D6" + // }] + // }`, + // Checks: []resource.TestCheckFunc{ + // resource.TestCheckResourceAttr(resourceName, "type", "vm"), + // resource.TestCheckResourceAttr(resourceName, "policies.0.policy_name", "D6"), + // }, + // }, + // // ! Updates testing + // Updates: []testsacc.TFConfig{ + // { + // TFConfig: ` + // resource "cloudavenue_backup" "example" { + // type = "vm" + // target_name = cloudavenue_vm.example.name + // policies = [{ + // policy_name = "D6" + // }, + // { + // policy_name = "D30" + // }] + // }`, + // Checks: []resource.TestCheckFunc{ + // resource.TestCheckResourceAttr(resourceName, "policies.0.policy_name", "D6"), + // resource.TestCheckResourceAttr(resourceName, "policies.1.policy_name", "D30"), + // }, + // }, + // }, + // // ! Imports testing + // Imports: []testsacc.TFImport{ + // { + // ImportStateIDFunc: testAccBackupResourceImportStateIDFuncWithTypeAndTargetName(resourceName), + // ImportState: true, + // ImportStateVerify: true, + // }, + // }, + // } + // }, } } diff --git a/templates/data-sources/backup.md.tmpl b/templates/data-sources/backup.md.tmpl new file mode 100644 index 000000000..d5075e3c9 --- /dev/null +++ b/templates/data-sources/backup.md.tmpl @@ -0,0 +1,25 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Backup" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +{{ if .HasExample -}} +## Example Usage + +{{ tffile .ExampleFile }} +{{- end }} + +{{ .SchemaMarkdown | trimspace }} + +{{ if .HasImport -}} +## Import + +Import is supported using the following syntax: +{{ codefile "shell" .ImportFile }} +{{- end }} \ No newline at end of file