diff --git a/README.md b/README.md index 7160b6b2c..833090867 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ A CLI tool that generates `tf`/`json` and `tfstate` files based on existing infr * [IBM Cloud](/docs/ibmcloud.md) * Cloud * [DigitalOcean](/docs/digitalocean.md) + * [BizflyCloud](/docs/bizflycloud.md) * [Equinix Metal](/docs/equinixmetal.md) * [Fastly](/docs/fastly.md) * [Heroku](/docs/heroku.md) @@ -280,6 +281,7 @@ Links to download Terraform provider plugins: * Alicloud provider >1.57.1 - [here](https://releases.hashicorp.com/terraform-provider-alicloud/) * Cloud * DigitalOcean provider >1.9.1 - [here](https://releases.hashicorp.com/terraform-provider-digitalocean/) + * BizflyCloud provider >=0.1.11 - [here](https://github.com/bizflycloud/terraform-provider-bizflycloud/releases) * Heroku provider >2.2.1 - [here](https://releases.hashicorp.com/terraform-provider-heroku/) * LaunchDarkly provider >=2.1.1 - [here](https://releases.hashicorp.com/terraform-provider-launchdarkly/) * Linode provider >1.8.0 - [here](https://releases.hashicorp.com/terraform-provider-linode/) diff --git a/cmd/provider_cmd_bizflycloud.go b/cmd/provider_cmd_bizflycloud.go new file mode 100644 index 000000000..550ff1dc3 --- /dev/null +++ b/cmd/provider_cmd_bizflycloud.go @@ -0,0 +1,44 @@ +// Copyright 2024 The Terraformer Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package cmd + +import ( + bizflycloud_terraforming "github.com/GoogleCloudPlatform/terraformer/providers/bizflycloud" + "github.com/GoogleCloudPlatform/terraformer/terraformutils" + "github.com/spf13/cobra" +) + +func newCmdBizflyCloudImporter(options ImportOptions) *cobra.Command { + cmd := &cobra.Command{ + Use: "bizflycloud", + Short: "Import current state to Terraform configuration from Bizfly Cloud", + Long: "Import current state to Terraform configuration from Bizfly Cloud", + RunE: func(cmd *cobra.Command, args []string) error { + provider := newBizflyCloudProvider() + err := Import(provider, options, []string{}) + if err != nil { + return err + } + return nil + }, + } + + cmd.AddCommand(listCmd(newBizflyCloudProvider())) + baseProviderFlags(cmd.PersistentFlags(), &options, "instance", "instance=name1:name2:name3") + return cmd +} + +func newBizflyCloudProvider() terraformutils.ProviderGenerator { + return &bizflycloud_terraforming.BizflyCloudProvider{} +} diff --git a/cmd/root.go b/cmd/root.go index 3099161f0..2370eee99 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -55,6 +55,7 @@ func providerImporterSubcommands() []func(options ImportOptions) *cobra.Command newCmdVultrImporter, newCmdYandexImporter, newCmdIonosCloudImporter, + newCmdBizflyCloudImporter, // Infrastructure Software newCmdKubernetesImporter, newCmdOctopusDeployImporter, @@ -112,6 +113,7 @@ func providerGenerators() map[string]func() terraformutils.ProviderGenerator { newOpenStackProvider, newTencentCloudProvider, newVultrProvider, + newBizflyCloudProvider, // Infrastructure Software newKubernetesProvider, newOctopusDeployProvider, diff --git a/docs/bizflycloud.md b/docs/bizflycloud.md new file mode 100644 index 000000000..214c3e8c9 --- /dev/null +++ b/docs/bizflycloud.md @@ -0,0 +1,33 @@ +### Use with BizflyCloud + +Example: + +``` +export BIZFLYCLOUD_PROJECT_ID=[BIZFLYCLOUD_PROJECT_ID] +export BIZFLYCLOUD_REGION=[BIZFLYCLOUD_REGION] +export BIZFLYCLOUD_EMAIL=[BIZFLYCLOUD_EMAIL] +export BIZFLYCLOUD_PASSWORD=[BIZFLYCLOUD_PASSWORD] +./terraformer import bizflycloud -r server,database +``` + +List of supported BizflyCloud resources: + +* `server` + * `bizflycloud_server` + * `bizflycloud_network_interface_attachment` + * `bizflycloud_network_interface` + * `bizflycloud_volume_attachment` + * `bizflycloud_volume` + * `bizflycloud_vpc_network` + * `bizflycloud_wan_ip` + * `bizflycloud_firewall` + * `bizflycloud_ssh_key` +* `database` + * `bizflycloud_cloud_database_instance` +* `load_balancer` + * `bizflycloud_loadbalancer` + * `bizflycloud_loadbalancer_listener` + * `bizflycloud_loadbalancer_l7policy` + * `bizflycloud_loadbalancer_pool` +* `kubernetes_engine` + * `bizflycloud_kubernetes` \ No newline at end of file diff --git a/go.mod b/go.mod index ac705d93b..950ec5759 100644 --- a/go.mod +++ b/go.mod @@ -165,7 +165,7 @@ require ( github.com/zclconf/go-cty v1.11.0 github.com/zorkian/go-datadog-api v2.30.0+incompatible golang.org/x/oauth2 v0.12.0 - golang.org/x/text v0.14.0 + golang.org/x/text v0.16.0 gonum.org/v1/gonum v0.7.0 google.golang.org/api v0.131.0 google.golang.org/genproto v0.0.0-20230629202037-9506855d4529 @@ -196,7 +196,7 @@ require github.com/newrelic/newrelic-client-go v0.79.0 require ( github.com/Azure/azure-pipeline-go v0.2.2 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect github.com/Azure/go-autorest/autorest/azure/cli v0.4.4 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect @@ -253,7 +253,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/jsonapi v1.0.0 // indirect @@ -321,14 +321,14 @@ require ( github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.mongodb.org/mongo-driver v1.7.5 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.17.0 // indirect + golang.org/x/crypto v0.25.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/tools v0.23.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/grpc v1.56.3 // indirect @@ -376,7 +376,7 @@ require ( github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect github.com/go-openapi/swag v0.19.14 // indirect - github.com/golang-jwt/jwt/v4 v4.4.3 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/s2a-go v0.1.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect @@ -393,6 +393,7 @@ require ( ) require ( + github.com/bizflycloud/gobizfly v1.1.3 github.com/gofrs/uuid/v3 v3.1.2 github.com/ionos-cloud/sdk-go-cert-manager v1.0.0 github.com/ionos-cloud/sdk-go-container-registry v1.0.0 @@ -419,6 +420,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tat v1.0.392 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tcaplusdb v1.0.392 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.0.392 + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 ) replace gopkg.in/jarcoal/httpmock.v1 => github.com/jarcoal/httpmock v1.0.5 diff --git a/go.sum b/go.sum index 31eccc180..b25dad68e 100644 --- a/go.sum +++ b/go.sum @@ -222,6 +222,8 @@ github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4Uw github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= github.com/Azure/go-autorest/autorest/azure/cli v0.2.0/go.mod h1:WWTbGPvkAg3I4ms2j2s+Zr5xCGwGqTQh+6M2ZqOczkE= github.com/Azure/go-autorest/autorest/azure/cli v0.4.4 h1:iuooz5cZL6VRcO7DVSFYxRcouqn6bFVE/e77Wts50Zk= github.com/Azure/go-autorest/autorest/azure/cli v0.4.4/go.mod h1:yAQ2b6eP/CmLPnmLvxtT1ALIY3OR1oFcCqVBi8vHiTc= @@ -568,6 +570,12 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= +github.com/bizflycloud/gobizfly v1.0.27 h1:TECKDUbf1NVXDaQO3ltcjL7u8LnCGXq5FQu+oj6dhsI= +github.com/bizflycloud/gobizfly v1.0.27/go.mod h1:Zav85BLm6aSbfM6NRFUmmWzkVfXlQ1YoRTl+dFQJmho= +github.com/bizflycloud/gobizfly v1.1.0 h1:gb5J6yGqhoqafXD5N2geZtY/Vh2Yoj+nbjG6zQcOnr4= +github.com/bizflycloud/gobizfly v1.1.0/go.mod h1:Zav85BLm6aSbfM6NRFUmmWzkVfXlQ1YoRTl+dFQJmho= +github.com/bizflycloud/gobizfly v1.1.3 h1:4lqGLSJmdLi93uAAS5BZcUpR1lyNmWPj12rWu+GkvqQ= +github.com/bizflycloud/gobizfly v1.1.3/go.mod h1:Zav85BLm6aSbfM6NRFUmmWzkVfXlQ1YoRTl+dFQJmho= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= @@ -787,6 +795,8 @@ github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= @@ -854,6 +864,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v35 v35.1.0 h1:KkwZnKWQ/0YryvXjZlCN/3EGRJNp6VCZPKo+RG9mG28= github.com/google/go-github/v35 v35.1.0/go.mod h1:s0515YVTI+IMrDoy9Y4pHt9ShGpzHvHO8rZ7L7acgvs= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -1752,8 +1764,13 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1768,6 +1785,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1799,6 +1818,8 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1864,8 +1885,14 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1910,8 +1937,12 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2000,13 +2031,25 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2018,8 +2061,13 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2097,6 +2145,11 @@ golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= 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.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/tools/cmd/cover v0.1.0-deprecated h1:Rwy+mWYz6loAF+LnG1jHG/JWMHRMMC2/1XX3Ejkx9lA= golang.org/x/tools/cmd/cover v0.1.0-deprecated/go.mod h1:hMDiIvlpN1NoVgmjLjUJE9tMHyxHjFX7RuQ+rW12mSA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/providers/bizflycloud/bizflycloud_provider.go b/providers/bizflycloud/bizflycloud_provider.go new file mode 100644 index 000000000..035431186 --- /dev/null +++ b/providers/bizflycloud/bizflycloud_provider.go @@ -0,0 +1,117 @@ +// Copyright 2019 The Terraformer Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bizflycloud + +import ( + "errors" + "os" + + "github.com/GoogleCloudPlatform/terraformer/terraformutils" +) + +type BizflyCloudProvider struct { //nolint + terraformutils.Provider + authMethod string + region string + email string + password string + appCredID string + appCredSecret string + projectID string +} + +func (p *BizflyCloudProvider) Init(args []string) error { + if os.Getenv("BIZFLYCLOUD_AUTH_METHOD") == "" { + p.authMethod = "password" + } + + if os.Getenv("BIZFLYCLOUD_PROJECT_ID") == "" { + return errors.New("set BIZFLYCLOUD_PROJECT_ID env var") + } + p.projectID = os.Getenv("BIZFLYCLOUD_PROJECT_ID") + + if os.Getenv("BIZFLYCLOUD_REGION") == "" { + return errors.New("set BIZFLYCLOUD_REGION env var") + } + p.region = os.Getenv("BIZFLYCLOUD_REGION") + + p.appCredID = "" + p.appCredSecret = "" + p.email = "" + p.password = "" + if os.Getenv("BIZFLYCLOUD_EMAIL") == "" && p.authMethod == "password" { + return errors.New("set BIZFLYCLOUD_EMAIL env var") + } + p.email = os.Getenv("BIZFLYCLOUD_EMAIL") + + if os.Getenv("BIZFLYCLOUD_PASSWORD") == "" && p.authMethod == "password" { + return errors.New("set BIZFLYCLOUD_PASSWORD env var") + } + p.password = os.Getenv("BIZFLYCLOUD_PASSWORD") + + if os.Getenv("BIZFLYCLOUD_APP_CRED_ID") == "" && p.authMethod == "application_credential" { + return errors.New("set BIZFLYCLOUD_APP_CRED_ID env var") + } + p.appCredID = os.Getenv("BIZFLYCLOUD_APP_CRED_ID") + + if os.Getenv("BIZFLYCLOUD_APP_CRED_SECRET") == "" && p.authMethod == "application_credential" { + return errors.New("set BIZFLYCLOUD_APP_CRED_SECRET env var") + } + p.appCredSecret = os.Getenv("BIZFLYCLOUD_APP_CRED_SECRET") + + return nil +} + +func (p *BizflyCloudProvider) GetName() string { + return "bizflycloud" +} + +func (p *BizflyCloudProvider) GetProviderData(arg ...string) map[string]interface{} { + return map[string]interface{}{} +} + +func (BizflyCloudProvider) GetResourceConnections() map[string]map[string][]string { + return map[string]map[string][]string{} +} + +func (p *BizflyCloudProvider) GetSupportedService() map[string]terraformutils.ServiceGenerator { + return map[string]terraformutils.ServiceGenerator{ + "server": &ServerGenerator{}, + "database": &CloudDatabaseGenerator{}, + "load_balancer": &LoadBalancerGenerator{}, + "kubernetes_engine": &KubernetesClusterGenerator{}, + } +} + +func (p *BizflyCloudProvider) InitService(serviceName string, verbose bool) error { + var isSupported bool + if _, isSupported = p.GetSupportedService()[serviceName]; !isSupported { + return errors.New("bizflycloud: " + serviceName + " not supported service") + } + p.Service = p.GetSupportedService()[serviceName] + p.Service.SetName(serviceName) + p.Service.SetVerbose(verbose) + p.Service.SetProviderName(p.GetName()) + p.Service.SetArgs(map[string]interface{}{ + "auth_method": p.authMethod, + "email": p.email, + "password": p.password, + "app_credential_id": p.appCredID, + "app_credential_secret": p.appCredSecret, + "project_id": p.projectID, + "region_name": p.region, + }) + return nil +} diff --git a/providers/bizflycloud/bizflycloud_service.go b/providers/bizflycloud/bizflycloud_service.go new file mode 100644 index 000000000..97fb66c23 --- /dev/null +++ b/providers/bizflycloud/bizflycloud_service.go @@ -0,0 +1,68 @@ +// Copyright 2019 The Terraformer Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bizflycloud + +import ( + "context" + "log" + "time" + + "github.com/GoogleCloudPlatform/terraformer/terraformutils" + "github.com/bizflycloud/gobizfly" +) + +type BizflyCloudService struct { //nolint + terraformutils.Service +} + +func (s *BizflyCloudService) generateClient() *gobizfly.Client { + client, err := gobizfly.NewClient(gobizfly.WithProjectID(s.Args["project_id"].(string)), + gobizfly.WithRegionName(s.Args["region_name"].(string))) // nolint + + if err != nil { + log.Fatal(err) + } + ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*10) + defer cancelFunc() + var tok *gobizfly.Token + if s.Args["auth_method"] == "password" { + tok, err = client.Token.Create(ctx, &gobizfly.TokenCreateRequest{ + AuthMethod: s.Args["auth_method"].(string), + Username: s.Args["email"].(string), + Password: s.Args["password"].(string), + AppCredID: "", + AppCredSecret: "", + ProjectID: s.Args["project_id"].(string), + }, + ) + } else { + tok, err = client.Token.Create(ctx, &gobizfly.TokenCreateRequest{ + AuthMethod: s.Args["auth_method"].(string), + Username: "", + Password: "", + AppCredID: s.Args["app_credential_id"].(string), + AppCredSecret: s.Args["app_credential_secret"].(string), + ProjectID: s.Args["project_id"].(string), + }, + ) + } + + if err != nil { + log.Fatal(err) + } + client.SetKeystoneToken(tok) + + return client +} diff --git a/providers/bizflycloud/database_instance.go b/providers/bizflycloud/database_instance.go new file mode 100644 index 000000000..427232d5b --- /dev/null +++ b/providers/bizflycloud/database_instance.go @@ -0,0 +1,124 @@ +// Copyright 2019 The Terraformer Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bizflycloud + +import ( + "context" + "strings" + + "github.com/GoogleCloudPlatform/terraformer/terraformutils" + "github.com/bizflycloud/gobizfly" +) + +type CloudDatabaseGenerator struct { + BizflyCloudService +} + +func (g *CloudDatabaseGenerator) loadDatabaseInstances(ctx context.Context, client *gobizfly.Client) ([]*gobizfly.CloudDatabaseInstance, error) { + list := []*gobizfly.CloudDatabaseInstance{} + + // create options. initially, these will be blank + opt := &gobizfly.CloudDatabaseListOption{} + for { + instances, err := client.CloudDatabase.Instances().List(ctx, opt) + if err != nil { + return nil, err + } + + nets, err := client.CloudServer.VPCNetworks().List(ctx) + if err != nil { + return nil, err + } + + for _, instance := range instances { + flavorName := "" + availabilityZone := "" + quantity := 0 + _availabilityZone := "" + networkIDs := []string{} + + for _, node := range instance.Nodes { + if node.Role == "primary" { + availabilityZone = node.AvailabilityZone + + _flavor := strings.Replace(node.Flavor, "nix.", "", -1) + _flavor = strings.Replace(_flavor, "_basic", "", -1) + _flavor = strings.Replace(_flavor, "_dedicated", "", -1) + _flavor = strings.Replace(_flavor, "_enterprise", "", -1) + flavorName = _flavor + + for _, network := range node.Addresses.Private { + for _, net := range nets { + if net.Name == network.Network { + networkIDs = append(networkIDs, net.ID) + } + } + } + } + + if node.Role != "primary" { + quantity = quantity + 1 + _availabilityZone = node.AvailabilityZone + } + } + + additionalFields := map[string]interface{}{ + "flavor_name": flavorName, + "availability_zone": availabilityZone, + "network_ids": networkIDs, + } + if quantity > 0 { + additionalFields["secondaries"] = map[string]interface{}{ + "availability_zone": _availabilityZone, + "quantity": quantity, + } + } + + instanceAutoScalingEnable := 0 + if instance.AutoScaling.Enable { + instanceAutoScalingEnable = 1 + } + additionalFields["autoscaling"] = map[string]interface{}{ + "enable": instanceAutoScalingEnable, + "volume_limited": instance.AutoScaling.Volume.Limited, + "volume_threshold": instance.AutoScaling.Volume.Threshold, + } + + additionalFields["volume_size"] = instance.Volume.Size + + g.Resources = append(g.Resources, terraformutils.NewResource( + instance.ID, + instance.Name, + "bizflycloud_cloud_database_instance", + "bizflycloud", + map[string]string{}, + []string{}, + additionalFields)) + list = append(list, instance) + } + break + } + + return list, nil +} + +func (g *CloudDatabaseGenerator) InitResources() error { + client := g.generateClient() + _, err := g.loadDatabaseInstances(context.TODO(), client) + if err != nil { + return err + } + return nil +} diff --git a/providers/bizflycloud/kubernetes_cluster.go b/providers/bizflycloud/kubernetes_cluster.go new file mode 100644 index 000000000..64334ba54 --- /dev/null +++ b/providers/bizflycloud/kubernetes_cluster.go @@ -0,0 +1,93 @@ +// Copyright 2019 The Terraformer Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bizflycloud + +import ( + "context" + + "golang.org/x/exp/slices" + + "github.com/GoogleCloudPlatform/terraformer/terraformutils" + "github.com/bizflycloud/gobizfly" +) + +type KubernetesClusterGenerator struct { + BizflyCloudService +} + +func (g *KubernetesClusterGenerator) loadKubernetesClusters(ctx context.Context, client *gobizfly.Client) ([]*gobizfly.FullCluster, error) { + list := []*gobizfly.FullCluster{} + + // create options. initially, these will be blank + opt := &gobizfly.ListOptions{} + clusters, err := client.KubernetesEngine.List(ctx, opt) + if err != nil { + return nil, err + } + + networkIDs := []string{} + networkNames := map[string]string{} + for _, _cluster := range clusters { + cluster, err := client.KubernetesEngine.Get(ctx, _cluster.UID) + if err != nil { + return nil, err + } + + if !slices.Contains(networkIDs, cluster.VPCNetworkID) { + net, err := client.CloudServer.VPCNetworks().Get(ctx, cluster.VPCNetworkID) + if err != nil { + return nil, err + } + + networkIDs = append(networkIDs, cluster.VPCNetworkID) + networkNames[net.ID] = net.Name + networkName := net.Name + if networkName == "" { + networkName = net.ID + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + net.ID, + networkName, + "bizflycloud_vpc_network", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{"is_default": net.IsDefault})) + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + cluster.UID, + cluster.Name, + "bizflycloud_kubernetes", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{"vpc_network_id": "${bizflycloud_vpc_network.tfer--" + networkNames[cluster.VPCNetworkID] + ".id}"})) + list = append(list, cluster) + } + + return list, nil +} + +func (g *KubernetesClusterGenerator) InitResources() error { + client := g.generateClient() + _, err := g.loadKubernetesClusters(context.TODO(), client) + if err != nil { + return err + } + + return nil +} diff --git a/providers/bizflycloud/loadbalancer.go b/providers/bizflycloud/loadbalancer.go new file mode 100644 index 000000000..9a8475b14 --- /dev/null +++ b/providers/bizflycloud/loadbalancer.go @@ -0,0 +1,190 @@ +// Copyright 2019 The Terraformer Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bizflycloud + +import ( + "context" + + "github.com/GoogleCloudPlatform/terraformer/terraformutils" + "github.com/bizflycloud/gobizfly" +) + +type LoadBalancerGenerator struct { + BizflyCloudService +} + +func (g *LoadBalancerGenerator) listLoadBalancers(ctx context.Context, client *gobizfly.Client) ([]*gobizfly.LoadBalancer, error) { + opts := &gobizfly.ListOptions{} + + loadBalancers, err := client.CloudLoadBalancer.List(ctx, opts) + if err != nil { + return nil, err + } + + for _, loadBalancer := range loadBalancers { + g.Resources = append(g.Resources, terraformutils.NewSimpleResource( + loadBalancer.ID, + loadBalancer.Name, + "bizflycloud_loadbalancer", + "bizflycloud", + []string{})) + } + + return loadBalancers, nil +} + +func (g *LoadBalancerGenerator) listLoadBalancerListeners(ctx context.Context, client *gobizfly.Client, loadBalancers []*gobizfly.LoadBalancer, pools []*gobizfly.CloudLoadBalancerPool) ([]*gobizfly.CloudLoadBalancerListener, error) { + list := []*gobizfly.CloudLoadBalancerListener{} + + opts := &gobizfly.ListOptions{} + l7Policies := []map[string]string{} + for _, loadBalancer := range loadBalancers { + listeners, err := client.CloudLoadBalancer.Listeners().List(ctx, loadBalancer.ID, opts) + if err != nil { + return nil, err + } + + list = append(list, listeners...) + defaultPoolName := "" + for _, listener := range listeners { + for _, policy := range listener.L7Policies { + l7Policies = append(l7Policies, map[string]string{ + "PolicyID": policy.ID, + "ListenerName": listener.Name, + }) + } + + for _, pool := range pools { + if pool.ID == listener.DefaultPoolID { + defaultPoolName = pool.Name + break + } + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + listener.ID, + listener.Name, + "bizflycloud_loadbalancer_listener", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{ + "load_balancer_id": "${bizflycloud_loadbalancer.tfer--" + loadBalancer.Name + ".id}", + "default_pool_id": "${bizflycloud_loadbalancer_pool.tfer--" + defaultPoolName + ".id}", + })) + } + } + + for _, l7Policy := range l7Policies { + policy, err := client.CloudLoadBalancer.L7Policies().Get(ctx, l7Policy["PolicyID"]) + if err != nil { + return nil, err + } + if policy.Name == "" { + policy.Name = policy.ID + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + policy.ID, + policy.Name, + "bizflycloud_loadbalancer_l7policy", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{ + "listener_id": "${bizflycloud_loadbalancer_listener.tfer--" + l7Policy["ListenerName"] + ".id}"})) + } + return list, nil + +} + +func (g *LoadBalancerGenerator) listLoadBalancerPools(ctx context.Context, client *gobizfly.Client, loadBalancers []*gobizfly.LoadBalancer) ([]*gobizfly.CloudLoadBalancerPool, error) { + list := []*gobizfly.CloudLoadBalancerPool{} + + opts := &gobizfly.ListOptions{} + for _, loadBalancer := range loadBalancers { + pools, err := client.CloudLoadBalancer.Pools().List(ctx, loadBalancer.ID, opts) + if err != nil { + return nil, err + } + + list = append(list, pools...) + for _, pool := range pools { + additionalFields := map[string]interface{}{"load_balancer_id": "${bizflycloud_loadbalancer.tfer--" + loadBalancer.Name + ".id}"} + if pool.HealthMonitorID != "" { + healthmonitor, err := client.CloudLoadBalancer.HealthMonitors().Get(ctx, pool.HealthMonitorID) + if err != nil { + return nil, err + } + + additionalFields["health_monitor"] = map[string]interface{}{ + "name": healthmonitor.Name, + "type": healthmonitor.Type, + "delay": healthmonitor.Delay, + "max_retries": healthmonitor.MaxRetries, + "max_retries_down": healthmonitor.MaxRetriesDown, + "timeout": healthmonitor.TimeOut, + "http_method": healthmonitor.HTTPMethod, + "url_path": healthmonitor.URLPath, + "expected_code": healthmonitor.ExpectedCodes, + } + } + + _members, err := client.CloudLoadBalancer.Members().List(ctx, pool.ID, opts) + if err != nil { + return nil, err + } + members := []map[string]interface{}{} + for _, member := range _members { + members = append(members, map[string]interface{}{ + "name": member.Name, + "weight": member.Weight, + "address": member.Address, + "protocol_port": member.ProtocolPort, + }) + } + if len(members) > 0 { + additionalFields["members"] = members + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + pool.ID, + pool.Name, + "bizflycloud_loadbalancer_pool", + "bizflycloud", + map[string]string{}, + []string{}, + additionalFields)) + } + } + return list, nil +} + +func (g *LoadBalancerGenerator) InitResources() error { + client := g.generateClient() + loadBalancers, err := g.listLoadBalancers(context.TODO(), client) + if err != nil { + return err + } + pools, err := g.listLoadBalancerPools(context.TODO(), client, loadBalancers) + if err != nil { + return err + } + _, err = g.listLoadBalancerListeners(context.TODO(), client, loadBalancers, pools) + if err != nil { + return err + } + return nil +} diff --git a/providers/bizflycloud/server.go b/providers/bizflycloud/server.go new file mode 100644 index 000000000..89f932840 --- /dev/null +++ b/providers/bizflycloud/server.go @@ -0,0 +1,350 @@ +// Copyright 2019 The Terraformer Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bizflycloud + +import ( + "context" + "golang.org/x/exp/slices" + + "github.com/GoogleCloudPlatform/terraformer/terraformutils" + "github.com/bizflycloud/gobizfly" +) + +type ServerGenerator struct { + BizflyCloudService +} + +func (g *ServerGenerator) listCloudServerVPCNetworks(ctx context.Context, client *gobizfly.Client) ([]*gobizfly.VPCNetwork, error) { + networks := []*gobizfly.VPCNetwork{} + + networks, err := client.CloudServer.VPCNetworks().List(ctx) + if err != nil { + return networks, err + } + + for _, network := range networks { + networkName := network.Name + if networkName == "" { + networkName = network.ID + } + g.Resources = append(g.Resources, terraformutils.NewResource( + network.ID, + networkName, + "bizflycloud_vpc_network", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{"is_default": network.IsDefault})) + } + + return networks, nil +} + +func (g *ServerGenerator) listCloudServerFirewalls(ctx context.Context, client *gobizfly.Client) ([]*gobizfly.Firewall, error) { + firewalls := []*gobizfly.Firewall{} + opts := &gobizfly.ListOptions{} + + firewalls, err := client.CloudServer.Firewalls().List(ctx, opts) + if err != nil { + return firewalls, err + } + + for _, firewall := range firewalls { + g.Resources = append(g.Resources, terraformutils.NewSimpleResource( + firewall.ID, + firewall.Name, + "bizflycloud_firewall", + "bizflycloud", + []string{})) + } + + return firewalls, nil +} + +func (g *ServerGenerator) listCloudServerVPCNetworkInterfaces(ctx context.Context, client *gobizfly.Client, networks []*gobizfly.VPCNetwork, firewalls []*gobizfly.Firewall) ([]*gobizfly.NetworkInterface, error) { + interfaces := []*gobizfly.NetworkInterface{} + opts := &gobizfly.ListNetworkInterfaceOptions{} + + interfaces, err := client.CloudServer.NetworkInterfaces().List(ctx, opts) + if err != nil { + return interfaces, err + } + + for _, networkInterface := range interfaces { + networkID := networkInterface.NetworkID + firewallIDs := []string{} + for _, net := range networks { + if net.ID == networkID { + if net.Name == "" { + networkID = "${bizflycloud_vpc_network.tfer--" + net.ID + ".id}" + } + networkID = "${bizflycloud_vpc_network.tfer--" + net.Name + ".id}" + } + } + + for _, fw := range firewalls { + if slices.Contains(networkInterface.SecurityGroups, fw.ID) { + firewallIDs = append(firewallIDs, "${bizflycloud_firewall.tfer--"+fw.Name+".id}") + } + } + + if networkInterface.Name == "" { + networkInterface.Name = networkInterface.ID + } + + additionalFields := map[string]interface{}{ + "fixed_ip": networkInterface.FixedIps[0].IPAddress, + "firewall_ids": firewallIDs, + "network_id": networkID, + "name": networkInterface.Name, + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + networkInterface.ID, + networkInterface.Name, + "bizflycloud_network_interface", + "bizflycloud", + map[string]string{}, + []string{}, + additionalFields)) + } + + return interfaces, nil +} + +func (g *ServerGenerator) listCloudServerPublicNetworkInterfaces(ctx context.Context, client *gobizfly.Client, firewalls []*gobizfly.Firewall) ([]*gobizfly.CloudServerPublicNetworkInterface, error) { + interfaces := []*gobizfly.CloudServerPublicNetworkInterface{} + + interfaces, err := client.CloudServer.PublicNetworkInterfaces().List(ctx) + if err != nil { + return interfaces, err + } + + for _, networkInterface := range interfaces { + firewallIDs := []string{} + for _, fw := range firewalls { + if slices.Contains(networkInterface.SecurityGroups, fw.ID) { + firewallIDs = append(firewallIDs, "${bizflycloud_firewall.tfer--"+fw.Name+".id}") + } + } + + if networkInterface.Name == "" { + networkInterface.Name = networkInterface.ID + } + + additionalFields := map[string]interface{}{ + "availability_zone": networkInterface.AvailabilityZone, + "firewall_ids": firewallIDs, + "name": networkInterface.Name, + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + networkInterface.ID, + networkInterface.Name, + "bizflycloud_wan_ip", + "bizflycloud", + map[string]string{}, + []string{}, + additionalFields)) + } + + return interfaces, nil +} + +func (g *ServerGenerator) listCloudServerSSHKeys(ctx context.Context, client *gobizfly.Client) ([]*gobizfly.KeyPair, error) { + keypairs := []*gobizfly.KeyPair{} + + keypairs, err := client.CloudServer.SSHKeys().List(ctx, &gobizfly.ListOptions{}) + if err != nil { + return keypairs, err + } + + for _, keypair := range keypairs { + g.Resources = append(g.Resources, terraformutils.NewSimpleResource( + keypair.SSHKeyPair.Name, + keypair.SSHKeyPair.Name, + "bizflycloud_ssh_key", + "bizflycloud", + []string{})) + } + + return keypairs, nil +} + +func (g *ServerGenerator) listServers(ctx context.Context, client *gobizfly.Client, keypairs []*gobizfly.KeyPair) ([]*gobizfly.Server, error) { + opt := &gobizfly.ServerListOptions{} + servers, err := client.CloudServer.List(ctx, opt) + if err != nil { + return servers, err + } + + opts := &gobizfly.VolumeListOptions{} + if err != nil { + return nil, err + } + volumes, err := client.CloudServer.Volumes().List(ctx, opts) + + beingHandle := []string{} + for _, server := range servers { + for _, volume := range volumes { + if slices.Contains(beingHandle, volume.ID) { + continue + } + + // Rootdisk availabe + if len(volume.Attachments) == 0 && volume.Bootable == true { + continue + } + + // Datadisk + volumeName := volume.Name + if volumeName == "" { + volumeName = volume.ID + } + // Volume availabe + if len(volume.Attachments) == 0 { + beingHandle = append(beingHandle, volume.ID) + + g.Resources = append(g.Resources, terraformutils.NewResource( + volume.ID, + volumeName, + "bizflycloud_volume", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{"size": volume.Size})) + } + + // Datadisk in-use + if len(volume.Attachments) > 0 && volume.AttachedType == "datadisk" { + beingHandle = append(beingHandle, volume.ID) + + g.Resources = append(g.Resources, terraformutils.NewResource( + volume.ID, + volumeName, + "bizflycloud_volume", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{"size": volume.Size})) + + for _, attachment := range volume.Attachments { + if attachment.ServerID != server.ID { + continue + } + + g.Resources = append(g.Resources, terraformutils.NewResource( + volume.ID, + server.Name+volumeName, + "bizflycloud_volume_attachment", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{ + "server_id": "${bizflycloud_server.tfer--" + server.Name + ".id}", + "volume_id": "${bizflycloud_volume.tfer--" + volumeName + ".id}", + })) + break + } + } + + // Rootdisk + if len(volume.Attachments) > 0 && volume.AttachedType == "rootdisk" { + for _, attachment := range volume.Attachments { + if attachment.ServerID != server.ID { + continue + } + + beingHandle = append(beingHandle, volume.ID) + + _keypair := server.KeyName + for _, keypair := range keypairs { + if keypair.SSHKeyPair.Name == server.KeyName { + _keypair = "${bizflycloud_ssh_key.tfer--" + keypair.SSHKeyPair.Name + ".name}" + } + } + g.Resources = append(g.Resources, terraformutils.NewResource( + server.ID, + server.Name, + "bizflycloud_server", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{ + "root_disk_size": volume.Size, + "ssh_key": _keypair, + })) + + break + } + } + } + } + return servers, nil +} + +func (g *ServerGenerator) listNetworkAttachments(ctx context.Context, client *gobizfly.Client, servers []*gobizfly.Server, privateInterfaces []*gobizfly.NetworkInterface, publicInterfaces []*gobizfly.CloudServerPublicNetworkInterface) error { + + for _, server := range servers { + for _, net := range privateInterfaces { + if net.AttachedServer.ID == server.ID { + g.Resources = append(g.Resources, terraformutils.NewResource( + net.ID, + server.Name+"-"+net.Name, + "bizflycloud_network_interface_attachment", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{ + "server_id": "${bizflycloud_server.tfer--" + server.Name + ".id}", + "network_interface_id": "${bizflycloud_network_interface.tfer--" + net.Name + ".id}", + })) + } + } + + for _, net := range publicInterfaces { + if net.AttachedServer.ID == server.ID { + g.Resources = append(g.Resources, terraformutils.NewResource( + net.ID, + server.Name+"-"+net.Name, + "bizflycloud_network_interface_attachment", + "bizflycloud", + map[string]string{}, + []string{}, + map[string]interface{}{ + "server_id": "${bizflycloud_server.tfer--" + server.Name + ".id}", + "network_interface_id": "${bizflycloud_wan_ip.tfer--" + net.Name + ".id}", + })) + } + } + } + return nil +} + +func (g *ServerGenerator) InitResources() error { + client := g.generateClient() + networks, err := g.listCloudServerVPCNetworks(context.TODO(), client) + firewalls, err := g.listCloudServerFirewalls(context.TODO(), client) + vpcInterfaces, err := g.listCloudServerVPCNetworkInterfaces(context.TODO(), client, networks, firewalls) + publicInterfaces, err := g.listCloudServerPublicNetworkInterfaces(context.TODO(), client, firewalls) + keypairs, err := g.listCloudServerSSHKeys(context.TODO(), client) + servers, err := g.listServers(context.TODO(), client, keypairs) + err = g.listNetworkAttachments(context.TODO(), client, servers, vpcInterfaces, publicInterfaces) + if err != nil { + return err + } + + return nil +}