Merge pull request #15258 from hashicorp/jbardin/remove-providers
Remove providers from core
This commit is contained in:
commit
be900e8085
18
Makefile
18
Makefile
|
@ -20,17 +20,6 @@ dev: fmtcheck generate
|
||||||
quickdev: generate
|
quickdev: generate
|
||||||
@TF_DEV=1 sh -c "'$(CURDIR)/scripts/build.sh'"
|
@TF_DEV=1 sh -c "'$(CURDIR)/scripts/build.sh'"
|
||||||
|
|
||||||
# Shorthand for quickly building the core of Terraform. Note that some
|
|
||||||
# changes will require a rebuild of everything, in which case the dev
|
|
||||||
# target should be used.
|
|
||||||
core-dev: generate
|
|
||||||
go install -tags 'core' github.com/hashicorp/terraform
|
|
||||||
|
|
||||||
# Shorthand for quickly testing the core of Terraform (i.e. "not providers")
|
|
||||||
core-test: generate
|
|
||||||
@echo "Testing core packages..." && \
|
|
||||||
go test -tags 'core' $(TESTARGS) $(shell go list ./... | grep -v -E 'terraform/(builtin|vendor)')
|
|
||||||
|
|
||||||
# Shorthand for building and installing just one plugin for local testing.
|
# Shorthand for building and installing just one plugin for local testing.
|
||||||
# Run as (for example): make plugin-dev PLUGIN=provider-aws
|
# Run as (for example): make plugin-dev PLUGIN=provider-aws
|
||||||
plugin-dev: generate
|
plugin-dev: generate
|
||||||
|
@ -38,7 +27,7 @@ plugin-dev: generate
|
||||||
mv $(GOPATH)/bin/$(PLUGIN) $(GOPATH)/bin/terraform-$(PLUGIN)
|
mv $(GOPATH)/bin/$(PLUGIN) $(GOPATH)/bin/terraform-$(PLUGIN)
|
||||||
|
|
||||||
# test runs the unit tests
|
# test runs the unit tests
|
||||||
test: fmtcheck errcheck generate
|
test: fmtcheck generate
|
||||||
go test -i $(TEST) || exit 1
|
go test -i $(TEST) || exit 1
|
||||||
echo $(TEST) | \
|
echo $(TEST) | \
|
||||||
xargs -t -n4 go test $(TESTARGS) -timeout=60s -parallel=4
|
xargs -t -n4 go test $(TESTARGS) -timeout=60s -parallel=4
|
||||||
|
@ -98,9 +87,6 @@ fmt:
|
||||||
fmtcheck:
|
fmtcheck:
|
||||||
@sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'"
|
@sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'"
|
||||||
|
|
||||||
errcheck:
|
|
||||||
@sh -c "'$(CURDIR)/scripts/errcheck.sh'"
|
|
||||||
|
|
||||||
vendor-status:
|
vendor-status:
|
||||||
@govendor status
|
@govendor status
|
||||||
|
|
||||||
|
@ -109,4 +95,4 @@ vendor-status:
|
||||||
# under parallel conditions.
|
# under parallel conditions.
|
||||||
.NOTPARALLEL:
|
.NOTPARALLEL:
|
||||||
|
|
||||||
.PHONY: bin core-dev core-test cover default dev errcheck fmt fmtcheck generate plugin-dev quickdev test-compile test testacc testrace tools vendor-status vet
|
.PHONY: bin cover default dev fmt fmtcheck generate plugin-dev quickdev test-compile test testacc testrace tools vendor-status vet
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
||||||
terraformAWS "github.com/hashicorp/terraform/builtin/providers/aws"
|
terraformAWS "github.com/terraform-providers/terraform-provider-aws/aws"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New creates a new backend for S3 remote state.
|
// New creates a new backend for S3 remote state.
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/archive"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: archive.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/arukas"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: arukas.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package main
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/atlas"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: atlas.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/aws"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: aws.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/azure"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: azure.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/azurerm"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: azurerm.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/bitbucket"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: bitbucket.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/chef"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: chef.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/clc"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: clc.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/cloudflare"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: cloudflare.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/cloudstack"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: cloudstack.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/cobbler"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: cobbler.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/consul"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: consul.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/datadog"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: datadog.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/digitalocean"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: digitalocean.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/dme"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: dme.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/dns"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: dns.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package main
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/dnsimple"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: dnsimple.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/docker"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: docker.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/dyn"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: dyn.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/external"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: external.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/fastly"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: fastly.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/github"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: github.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/gitlab"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: gitlab.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/google"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: google.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/grafana"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: grafana.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/heroku"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: heroku.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/ignition"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: ignition.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/influxdb"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: influxdb.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/kubernetes"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: kubernetes.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/librato"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: librato.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/local"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: local.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/logentries"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: logentries.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package main
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/mailgun"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: mailgun.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/mysql"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: mysql.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/ns1"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: ns1.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package main
|
|
|
@ -1,15 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/null"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: func() terraform.ResourceProvider {
|
|
||||||
return null.Provider()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/openstack"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: openstack.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/opsgenie"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: opsgenie.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/ovh"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: ovh.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/packet"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: packet.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/pagerduty"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: pagerduty.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/postgresql"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: postgresql.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/powerdns"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: powerdns.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/profitbricks"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: profitbricks.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/rancher"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: func() terraform.ResourceProvider {
|
|
||||||
return rancher.Provider()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/random"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: func() terraform.ResourceProvider {
|
|
||||||
return random.Provider()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/rundeck"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: rundeck.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/scaleway"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: scaleway.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/softlayer"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: softlayer.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/spotinst"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: spotinst.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/statuscake"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: statuscake.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/template"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: template.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/terraform"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: terraform.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/tls"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: tls.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/triton"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: triton.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/ultradns"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: ultradns.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/vault"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: vault.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/vcd"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: vcd.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/builtin/providers/vsphere"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
|
||||||
ProviderFunc: vsphere.Provider,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
providers moved to github.com/terraform-providers
|
|
@ -1,93 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
type InstanceNetWork string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ClassicNet = InstanceNetWork("classic")
|
|
||||||
VpcNet = InstanceNetWork("vpc")
|
|
||||||
)
|
|
||||||
|
|
||||||
// timeout for common product, ecs e.g.
|
|
||||||
const defaultTimeout = 120
|
|
||||||
|
|
||||||
// timeout for long time progerss product, rds e.g.
|
|
||||||
const defaultLongTimeout = 1000
|
|
||||||
|
|
||||||
func getRegion(d *schema.ResourceData, meta interface{}) common.Region {
|
|
||||||
return meta.(*AliyunClient).Region
|
|
||||||
}
|
|
||||||
|
|
||||||
func notFoundError(err error) bool {
|
|
||||||
if e, ok := err.(*common.Error); ok &&
|
|
||||||
(e.StatusCode == 404 || e.ErrorResponse.Message == "Not found" || e.Code == InstanceNotfound) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protocol represents network protocol
|
|
||||||
type Protocol string
|
|
||||||
|
|
||||||
// Constants of protocol definition
|
|
||||||
const (
|
|
||||||
Http = Protocol("http")
|
|
||||||
Https = Protocol("https")
|
|
||||||
Tcp = Protocol("tcp")
|
|
||||||
Udp = Protocol("udp")
|
|
||||||
)
|
|
||||||
|
|
||||||
// ValidProtocols network protocol list
|
|
||||||
var ValidProtocols = []Protocol{Http, Https, Tcp, Udp}
|
|
||||||
|
|
||||||
// simple array value check method, support string type only
|
|
||||||
func isProtocolValid(value string) bool {
|
|
||||||
res := false
|
|
||||||
for _, v := range ValidProtocols {
|
|
||||||
if string(v) == value {
|
|
||||||
res = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultBusinessInfo = ecs.BusinessInfo{
|
|
||||||
Pack: "terraform",
|
|
||||||
}
|
|
||||||
|
|
||||||
// default region for all resource
|
|
||||||
const DEFAULT_REGION = "cn-beijing"
|
|
||||||
|
|
||||||
// default security ip for db
|
|
||||||
const DEFAULT_DB_SECURITY_IP = "127.0.0.1"
|
|
||||||
|
|
||||||
// we the count of create instance is only one
|
|
||||||
const DEFAULT_INSTANCE_COUNT = 1
|
|
||||||
|
|
||||||
// symbol of multiIZ
|
|
||||||
const MULTI_IZ_SYMBOL = "MAZ"
|
|
||||||
|
|
||||||
// default connect port of db
|
|
||||||
const DB_DEFAULT_CONNECT_PORT = "3306"
|
|
||||||
|
|
||||||
const COMMA_SEPARATED = ","
|
|
||||||
|
|
||||||
const COLON_SEPARATED = ":"
|
|
||||||
|
|
||||||
const LOCAL_HOST_IP = "127.0.0.1"
|
|
||||||
|
|
||||||
// Takes the result of flatmap.Expand for an array of strings
|
|
||||||
// and returns a []string
|
|
||||||
func expandStringList(configured []interface{}) []string {
|
|
||||||
vs := make([]string, 0, len(configured))
|
|
||||||
for _, v := range configured {
|
|
||||||
vs = append(vs, v.(string))
|
|
||||||
}
|
|
||||||
return vs
|
|
||||||
}
|
|
|
@ -1,138 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/denverdino/aliyungo/ess"
|
|
||||||
"github.com/denverdino/aliyungo/rds"
|
|
||||||
"github.com/denverdino/aliyungo/slb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config of aliyun
|
|
||||||
type Config struct {
|
|
||||||
AccessKey string
|
|
||||||
SecretKey string
|
|
||||||
Region common.Region
|
|
||||||
}
|
|
||||||
|
|
||||||
// AliyunClient of aliyun
|
|
||||||
type AliyunClient struct {
|
|
||||||
Region common.Region
|
|
||||||
ecsconn *ecs.Client
|
|
||||||
essconn *ess.Client
|
|
||||||
rdsconn *rds.Client
|
|
||||||
// use new version
|
|
||||||
ecsNewconn *ecs.Client
|
|
||||||
vpcconn *ecs.Client
|
|
||||||
slbconn *slb.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client for AliyunClient
|
|
||||||
func (c *Config) Client() (*AliyunClient, error) {
|
|
||||||
err := c.loadAndValidate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ecsconn, err := c.ecsConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ecsNewconn, err := c.ecsConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ecsNewconn.SetVersion(EcsApiVersion20160314)
|
|
||||||
|
|
||||||
rdsconn, err := c.rdsConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
slbconn, err := c.slbConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
vpcconn, err := c.vpcConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
essconn, err := c.essConn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &AliyunClient{
|
|
||||||
Region: c.Region,
|
|
||||||
ecsconn: ecsconn,
|
|
||||||
ecsNewconn: ecsNewconn,
|
|
||||||
vpcconn: vpcconn,
|
|
||||||
slbconn: slbconn,
|
|
||||||
rdsconn: rdsconn,
|
|
||||||
essconn: essconn,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const BusinessInfoKey = "Terraform"
|
|
||||||
|
|
||||||
func (c *Config) loadAndValidate() error {
|
|
||||||
err := c.validateRegion()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) validateRegion() error {
|
|
||||||
|
|
||||||
for _, valid := range common.ValidRegions {
|
|
||||||
if c.Region == valid {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("Not a valid region: %s", c.Region)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) ecsConn() (*ecs.Client, error) {
|
|
||||||
client := ecs.NewECSClient(c.AccessKey, c.SecretKey, c.Region)
|
|
||||||
client.SetBusinessInfo(BusinessInfoKey)
|
|
||||||
|
|
||||||
_, err := client.DescribeRegions()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) rdsConn() (*rds.Client, error) {
|
|
||||||
client := rds.NewRDSClient(c.AccessKey, c.SecretKey, c.Region)
|
|
||||||
client.SetBusinessInfo(BusinessInfoKey)
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) slbConn() (*slb.Client, error) {
|
|
||||||
client := slb.NewSLBClient(c.AccessKey, c.SecretKey, c.Region)
|
|
||||||
client.SetBusinessInfo(BusinessInfoKey)
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) vpcConn() (*ecs.Client, error) {
|
|
||||||
client := ecs.NewVPCClient(c.AccessKey, c.SecretKey, c.Region)
|
|
||||||
client.SetBusinessInfo(BusinessInfoKey)
|
|
||||||
return client, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
func (c *Config) essConn() (*ess.Client, error) {
|
|
||||||
client := ess.NewESSClient(c.AccessKey, c.SecretKey, c.Region)
|
|
||||||
client.SetBusinessInfo(BusinessInfoKey)
|
|
||||||
return client, nil
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"github.com/hashicorp/terraform/helper/hashcode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Generates a hash for the set hash function used by the ID
|
|
||||||
func dataResourceIdHash(ids []string) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
for _, id := range ids {
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", id))
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%d", hashcode.String(buf.String()))
|
|
||||||
}
|
|
|
@ -1,337 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"regexp"
|
|
||||||
"sort"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceAlicloudImages() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Read: dataSourceAlicloudImagesRead,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name_regex": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validateNameRegex,
|
|
||||||
},
|
|
||||||
"most_recent": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"owners": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validateImageOwners,
|
|
||||||
},
|
|
||||||
// Computed values.
|
|
||||||
"images": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"image_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"architecture": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"creation_time": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"image_owner_alias": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"os_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"os_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"platform": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
// Complex computed values
|
|
||||||
"disk_device_mappings": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
//Set: imageDiskDeviceMappingHash,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"device": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"snapshot_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"product_code": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"is_self_shared": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"is_subscribed": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"is_copied": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"is_support_io_optimized": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"image_version": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"progress": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"usage": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"tags": tagsSchema(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dataSourceAlicloudImagesDescriptionRead performs the Alicloud Image lookup.
|
|
||||||
func dataSourceAlicloudImagesRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
nameRegex, nameRegexOk := d.GetOk("name_regex")
|
|
||||||
owners, ownersOk := d.GetOk("owners")
|
|
||||||
mostRecent, mostRecentOk := d.GetOk("most_recent")
|
|
||||||
|
|
||||||
if nameRegexOk == false && ownersOk == false && mostRecentOk == false {
|
|
||||||
return fmt.Errorf("One of name_regex, owners or most_recent must be assigned")
|
|
||||||
}
|
|
||||||
|
|
||||||
params := &ecs.DescribeImagesArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
}
|
|
||||||
|
|
||||||
if ownersOk {
|
|
||||||
params.ImageOwnerAlias = ecs.ImageOwnerAlias(owners.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
var allImages []ecs.ImageType
|
|
||||||
|
|
||||||
for {
|
|
||||||
images, paginationResult, err := conn.DescribeImages(params)
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
allImages = append(allImages, images...)
|
|
||||||
|
|
||||||
pagination := paginationResult.NextPage()
|
|
||||||
if pagination == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
params.Pagination = *pagination
|
|
||||||
}
|
|
||||||
|
|
||||||
var filteredImages []ecs.ImageType
|
|
||||||
if nameRegexOk {
|
|
||||||
r := regexp.MustCompile(nameRegex.(string))
|
|
||||||
for _, image := range allImages {
|
|
||||||
// Check for a very rare case where the response would include no
|
|
||||||
// image name. No name means nothing to attempt a match against,
|
|
||||||
// therefore we are skipping such image.
|
|
||||||
if image.ImageName == "" {
|
|
||||||
log.Printf("[WARN] Unable to find Image name to match against "+
|
|
||||||
"for image ID %q, nothing to do.",
|
|
||||||
image.ImageId)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if r.MatchString(image.ImageName) {
|
|
||||||
filteredImages = append(filteredImages, image)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
filteredImages = allImages[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
var images []ecs.ImageType
|
|
||||||
if len(filteredImages) < 1 {
|
|
||||||
return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_image - multiple results found and `most_recent` is set to: %t", mostRecent.(bool))
|
|
||||||
if len(filteredImages) > 1 && mostRecent.(bool) {
|
|
||||||
// Query returned single result.
|
|
||||||
images = append(images, mostRecentImage(filteredImages))
|
|
||||||
} else {
|
|
||||||
images = filteredImages
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_image - Images found: %#v", images)
|
|
||||||
return imagesDescriptionAttributes(d, images, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate the numerous fields that the image description returns.
|
|
||||||
func imagesDescriptionAttributes(d *schema.ResourceData, images []ecs.ImageType, meta interface{}) error {
|
|
||||||
var ids []string
|
|
||||||
var s []map[string]interface{}
|
|
||||||
for _, image := range images {
|
|
||||||
mapping := map[string]interface{}{
|
|
||||||
"id": image.ImageId,
|
|
||||||
"architecture": image.Architecture,
|
|
||||||
"creation_time": image.CreationTime.String(),
|
|
||||||
"description": image.Description,
|
|
||||||
"image_id": image.ImageId,
|
|
||||||
"image_owner_alias": image.ImageOwnerAlias,
|
|
||||||
"os_name": image.OSName,
|
|
||||||
"os_type": image.OSType,
|
|
||||||
"name": image.ImageName,
|
|
||||||
"platform": image.Platform,
|
|
||||||
"status": image.Status,
|
|
||||||
"state": image.Status,
|
|
||||||
"size": image.Size,
|
|
||||||
"is_self_shared": image.IsSelfShared,
|
|
||||||
"is_subscribed": image.IsSubscribed,
|
|
||||||
"is_copied": image.IsCopied,
|
|
||||||
"is_support_io_optimized": image.IsSupportIoOptimized,
|
|
||||||
"image_version": image.ImageVersion,
|
|
||||||
"progress": image.Progress,
|
|
||||||
"usage": image.Usage,
|
|
||||||
"product_code": image.ProductCode,
|
|
||||||
|
|
||||||
// Complex types get their own functions
|
|
||||||
"disk_device_mappings": imageDiskDeviceMappings(image.DiskDeviceMappings.DiskDeviceMapping),
|
|
||||||
"tags": imageTagsMappings(d, image.ImageId, meta),
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_image - adding image mapping: %v", mapping)
|
|
||||||
ids = append(ids, image.ImageId)
|
|
||||||
s = append(s, mapping)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(dataResourceIdHash(ids))
|
|
||||||
if err := d.Set("images", s); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//Find most recent image
|
|
||||||
type imageSort []ecs.ImageType
|
|
||||||
|
|
||||||
func (a imageSort) Len() int {
|
|
||||||
return len(a)
|
|
||||||
}
|
|
||||||
func (a imageSort) Swap(i, j int) {
|
|
||||||
a[i], a[j] = a[j], a[i]
|
|
||||||
}
|
|
||||||
func (a imageSort) Less(i, j int) bool {
|
|
||||||
itime, _ := time.Parse(time.RFC3339, a[i].CreationTime.String())
|
|
||||||
jtime, _ := time.Parse(time.RFC3339, a[j].CreationTime.String())
|
|
||||||
return itime.Unix() < jtime.Unix()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the most recent Image out of a slice of images.
|
|
||||||
func mostRecentImage(images []ecs.ImageType) ecs.ImageType {
|
|
||||||
sortedImages := images
|
|
||||||
sort.Sort(imageSort(sortedImages))
|
|
||||||
return sortedImages[len(sortedImages)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a set of disk device mappings.
|
|
||||||
func imageDiskDeviceMappings(m []ecs.DiskDeviceMapping) []map[string]interface{} {
|
|
||||||
var s []map[string]interface{}
|
|
||||||
|
|
||||||
for _, v := range m {
|
|
||||||
mapping := map[string]interface{}{
|
|
||||||
"device": v.Device,
|
|
||||||
"size": v.Size,
|
|
||||||
"snapshot_id": v.SnapshotId,
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_image - adding disk device mapping: %v", mapping)
|
|
||||||
s = append(s, mapping)
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns a mapping of image tags
|
|
||||||
func imageTagsMappings(d *schema.ResourceData, imageId string, meta interface{}) map[string]string {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
tags, _, err := conn.DescribeTags(&ecs.DescribeTagsArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
ResourceType: ecs.TagResourceImage,
|
|
||||||
ResourceId: imageId,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[ERROR] DescribeTags for image got error: %#v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] DescribeTags for image : %v", tags)
|
|
||||||
return tagsToMap(tags)
|
|
||||||
}
|
|
|
@ -1,155 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudImagesDataSource_images(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudImagesDataSourceImagesConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_images.multi_image"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.#", "2"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.architecture", "x86_64"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.disk_device_mappings.#", "0"),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.multi_image", "images.0.creation_time", regexp.MustCompile("^20[0-9]{2}-")),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.multi_image", "images.0.image_id", regexp.MustCompile("^centos_6\\w{1,5}[64]{1}.")),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.image_owner_alias", "system"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.os_type", "linux"),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.multi_image", "images.0.name", regexp.MustCompile("^centos_6[a-zA-Z0-9_]{1,5}[64]{1}.")),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.progress", "100%"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.state", "Available"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.status", "Available"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.usage", "instance"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.0.tags.%", "0"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.architecture", "i386"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.disk_device_mappings.#", "0"),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.multi_image", "images.1.creation_time", regexp.MustCompile("^20[0-9]{2}-")),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.multi_image", "images.1.image_id", regexp.MustCompile("^centos_6[a-zA-Z0-9_]{1,5}[32]{1}.")),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.image_owner_alias", "system"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.os_type", "linux"),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.multi_image", "images.1.name", regexp.MustCompile("^centos_6\\w{1,5}[32]{1}.")),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.progress", "100%"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.state", "Available"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.status", "Available"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.usage", "instance"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.multi_image", "images.1.tags.%", "0"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudImagesDataSource_owners(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudImagesDataSourceOwnersConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_images.owners_filtered_image"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudImagesDataSource_ownersEmpty(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudImagesDataSourceEmptyOwnersConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_images.empty_owners_filtered_image"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_images.empty_owners_filtered_image", "most_recent", "true"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudImagesDataSource_nameRegexFilter(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudImagesDataSourceNameRegexConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_images.name_regex_filtered_image"),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.name_regex_filtered_image", "images.0.image_id", regexp.MustCompile("^centos_")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudImagesDataSource_imageNotInFirstPage(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudImagesDataSourceImageNotInFirstPageConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_images.name_regex_filtered_image"),
|
|
||||||
resource.TestMatchResourceAttr("data.alicloud_images.name_regex_filtered_image", "images.0.image_id", regexp.MustCompile("^ubuntu_14")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instance store test - using centos images
|
|
||||||
const testAccCheckAlicloudImagesDataSourceImagesConfig = `
|
|
||||||
data "alicloud_images" "multi_image" {
|
|
||||||
owners = "system"
|
|
||||||
name_regex = "^centos_6"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Testing owner parameter
|
|
||||||
const testAccCheckAlicloudImagesDataSourceOwnersConfig = `
|
|
||||||
data "alicloud_images" "owners_filtered_image" {
|
|
||||||
most_recent = true
|
|
||||||
owners = "system"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccCheckAlicloudImagesDataSourceEmptyOwnersConfig = `
|
|
||||||
data "alicloud_images" "empty_owners_filtered_image" {
|
|
||||||
most_recent = true
|
|
||||||
owners = ""
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Testing name_regex parameter
|
|
||||||
const testAccCheckAlicloudImagesDataSourceNameRegexConfig = `
|
|
||||||
data "alicloud_images" "name_regex_filtered_image" {
|
|
||||||
most_recent = true
|
|
||||||
owners = "system"
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64]{1}.*"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Testing image not in first page response
|
|
||||||
const testAccCheckAlicloudImagesDataSourceImageNotInFirstPageConfig = `
|
|
||||||
data "alicloud_images" "name_regex_filtered_image" {
|
|
||||||
most_recent = true
|
|
||||||
owners = "system"
|
|
||||||
name_regex = "^ubuntu_14.*_64"
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,127 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceAlicloudInstanceTypes() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Read: dataSourceAlicloudInstanceTypesRead,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"instance_type_family": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"cpu_core_count": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"memory_size": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
// Computed values.
|
|
||||||
"instance_types": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cpu_core_count": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"memory_size": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"family": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAlicloudInstanceTypesRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
cpu, _ := d.Get("cpu_core_count").(int)
|
|
||||||
mem, _ := d.Get("memory_size").(float64)
|
|
||||||
|
|
||||||
args, err := buildAliyunAlicloudInstanceTypesArgs(d, meta)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := conn.DescribeInstanceTypesNew(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var instanceTypes []ecs.InstanceTypeItemType
|
|
||||||
for _, types := range resp {
|
|
||||||
if cpu > 0 && types.CpuCoreCount != cpu {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if mem > 0 && types.MemorySize != mem {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
instanceTypes = append(instanceTypes, types)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(instanceTypes) < 1 {
|
|
||||||
return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_instance_type - Types found: %#v", instanceTypes)
|
|
||||||
return instanceTypesDescriptionAttributes(d, instanceTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func instanceTypesDescriptionAttributes(d *schema.ResourceData, types []ecs.InstanceTypeItemType) error {
|
|
||||||
var ids []string
|
|
||||||
var s []map[string]interface{}
|
|
||||||
for _, t := range types {
|
|
||||||
mapping := map[string]interface{}{
|
|
||||||
"id": t.InstanceTypeId,
|
|
||||||
"cpu_core_count": t.CpuCoreCount,
|
|
||||||
"memory_size": t.MemorySize,
|
|
||||||
"family": t.InstanceTypeFamily,
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_instance_type - adding type mapping: %v", mapping)
|
|
||||||
ids = append(ids, t.InstanceTypeId)
|
|
||||||
s = append(s, mapping)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(dataResourceIdHash(ids))
|
|
||||||
if err := d.Set("instance_types", s); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildAliyunAlicloudInstanceTypesArgs(d *schema.ResourceData, meta interface{}) (*ecs.DescribeInstanceTypesArgs, error) {
|
|
||||||
args := &ecs.DescribeInstanceTypesArgs{}
|
|
||||||
|
|
||||||
if v := d.Get("instance_type_family").(string); v != "" {
|
|
||||||
args.InstanceTypeFamily = v
|
|
||||||
}
|
|
||||||
|
|
||||||
return args, nil
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudInstanceTypesDataSource_basic(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudInstanceTypesDataSourceBasicConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_instance_types.4c8g"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_instance_types.4c8g", "instance_types.0.cpu_core_count", "4"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_instance_types.4c8g", "instance_types.0.memory_size", "8"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_instance_types.4c8g", "instance_types.0.id", "ecs.s3.large"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccCheckAlicloudInstanceTypesDataSourceBasicConfigUpdate,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_instance_types.4c8g"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_instance_types.4c8g", "instance_types.#", "1"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_instance_types.4c8g", "instance_types.0.cpu_core_count", "4"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_instance_types.4c8g", "instance_types.0.memory_size", "8"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccCheckAlicloudInstanceTypesDataSourceBasicConfig = `
|
|
||||||
data "alicloud_instance_types" "4c8g" {
|
|
||||||
cpu_core_count = 4
|
|
||||||
memory_size = 8
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccCheckAlicloudInstanceTypesDataSourceBasicConfigUpdate = `
|
|
||||||
data "alicloud_instance_types" "4c8g" {
|
|
||||||
instance_type_family= "ecs.s3"
|
|
||||||
cpu_core_count = 4
|
|
||||||
memory_size = 8
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,114 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceAlicloudRegions() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Read: dataSourceAlicloudRegionsRead,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"current": &schema.Schema{
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
//Computed value
|
|
||||||
"regions": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"region_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"local_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAlicloudRegionsRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
currentRegion := getRegion(d, meta)
|
|
||||||
|
|
||||||
resp, err := conn.DescribeRegions()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if resp == nil || len(resp) == 0 {
|
|
||||||
return fmt.Errorf("no matching regions found")
|
|
||||||
}
|
|
||||||
name, nameOk := d.GetOk("name")
|
|
||||||
current := d.Get("current").(bool)
|
|
||||||
var filterRegions []ecs.RegionType
|
|
||||||
for _, region := range resp {
|
|
||||||
if current {
|
|
||||||
if nameOk && common.Region(name.(string)) != currentRegion {
|
|
||||||
return fmt.Errorf("name doesn't match current region: %#v, please input again.", currentRegion)
|
|
||||||
}
|
|
||||||
if region.RegionId == currentRegion {
|
|
||||||
filterRegions = append(filterRegions, region)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if nameOk {
|
|
||||||
if common.Region(name.(string)) == region.RegionId {
|
|
||||||
filterRegions = append(filterRegions, region)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
filterRegions = append(filterRegions, region)
|
|
||||||
}
|
|
||||||
if len(filterRegions) < 1 {
|
|
||||||
return fmt.Errorf("Your query region returned no results. Please change your search criteria and try again.")
|
|
||||||
}
|
|
||||||
|
|
||||||
return regionsDescriptionAttributes(d, filterRegions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func regionsDescriptionAttributes(d *schema.ResourceData, regions []ecs.RegionType) error {
|
|
||||||
var ids []string
|
|
||||||
var s []map[string]interface{}
|
|
||||||
for _, region := range regions {
|
|
||||||
mapping := map[string]interface{}{
|
|
||||||
"id": region.RegionId,
|
|
||||||
"region_id": region.RegionId,
|
|
||||||
"local_name": region.LocalName,
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_regions - adding region mapping: %v", mapping)
|
|
||||||
ids = append(ids, string(region.RegionId))
|
|
||||||
s = append(s, mapping)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(dataResourceIdHash(ids))
|
|
||||||
if err := d.Set("regions", s); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudRegionsDataSource_regions(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudRegionsDataSourceRegionsConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_regions.region"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.region", "name", "cn-beijing"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.region", "current", "true"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.region", "regions.#", "1"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.region", "regions.0.id", "cn-beijing"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.region", "regions.0.region_id", "cn-beijing"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.region", "regions.0.local_name", "华北 2"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudRegionsDataSource_name(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudRegionsDataSourceNameConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_regions.name_filtered_region"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.name_filtered_region", "name", "cn-hangzhou")),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudRegionsDataSource_current(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudRegionsDataSourceCurrentConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_regions.current_filtered_region"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.current_filtered_region", "current", "true"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudRegionsDataSource_empty(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudRegionsDataSourceEmptyConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_regions.empty_params_region"),
|
|
||||||
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.empty_params_region", "regions.0.id", "cn-shenzhen"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.empty_params_region", "regions.0.region_id", "cn-shenzhen"),
|
|
||||||
resource.TestCheckResourceAttr("data.alicloud_regions.empty_params_region", "regions.0.local_name", "华南 1"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instance store test - using centos regions
|
|
||||||
const testAccCheckAlicloudRegionsDataSourceRegionsConfig = `
|
|
||||||
data "alicloud_regions" "region" {
|
|
||||||
name = "cn-beijing"
|
|
||||||
current = true
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Testing name parameter
|
|
||||||
const testAccCheckAlicloudRegionsDataSourceNameConfig = `
|
|
||||||
data "alicloud_regions" "name_filtered_region" {
|
|
||||||
name = "cn-hangzhou"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Testing current parameter
|
|
||||||
const testAccCheckAlicloudRegionsDataSourceCurrentConfig = `
|
|
||||||
data "alicloud_regions" "current_filtered_region" {
|
|
||||||
current = true
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Testing empty parmas
|
|
||||||
const testAccCheckAlicloudRegionsDataSourceEmptyConfig = `
|
|
||||||
data "alicloud_regions" "empty_params_region" {
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,137 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"log"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceAlicloudZones() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Read: dataSourceAlicloudZonesRead,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"available_instance_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"available_resource_creation": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"available_disk_category": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
// Computed values.
|
|
||||||
"zones": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"local_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"available_instance_types": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
},
|
|
||||||
"available_resource_creation": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
},
|
|
||||||
"available_disk_categories": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAlicloudZonesRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
insType, _ := d.Get("available_instance_type").(string)
|
|
||||||
resType, _ := d.Get("available_resource_creation").(string)
|
|
||||||
diskType, _ := d.Get("available_disk_category").(string)
|
|
||||||
|
|
||||||
resp, err := conn.DescribeZones(getRegion(d, meta))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var zoneTypes []ecs.ZoneType
|
|
||||||
for _, types := range resp {
|
|
||||||
if insType != "" && !constraints(types.AvailableInstanceTypes.InstanceTypes, insType) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if resType != "" && !constraints(types.AvailableResourceCreation.ResourceTypes, resType) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if diskType != "" && !constraints(types.AvailableDiskCategories.DiskCategories, diskType) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
zoneTypes = append(zoneTypes, types)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(zoneTypes) < 1 {
|
|
||||||
return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_zones - Zones found: %#v", zoneTypes)
|
|
||||||
return zonesDescriptionAttributes(d, zoneTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check array constraints str
|
|
||||||
func constraints(arr interface{}, v string) bool {
|
|
||||||
arrs := reflect.ValueOf(arr)
|
|
||||||
len := arrs.Len()
|
|
||||||
for i := 0; i < len; i++ {
|
|
||||||
if arrs.Index(i).String() == v {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func zonesDescriptionAttributes(d *schema.ResourceData, types []ecs.ZoneType) error {
|
|
||||||
var ids []string
|
|
||||||
var s []map[string]interface{}
|
|
||||||
for _, t := range types {
|
|
||||||
mapping := map[string]interface{}{
|
|
||||||
"id": t.ZoneId,
|
|
||||||
"local_name": t.LocalName,
|
|
||||||
"available_instance_types": t.AvailableInstanceTypes.InstanceTypes,
|
|
||||||
"available_resource_creation": t.AvailableResourceCreation.ResourceTypes,
|
|
||||||
"available_disk_categories": t.AvailableDiskCategories.DiskCategories,
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] alicloud_zones - adding zone mapping: %v", mapping)
|
|
||||||
ids = append(ids, t.ZoneId)
|
|
||||||
s = append(s, mapping)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(dataResourceIdHash(ids))
|
|
||||||
if err := d.Set("zones", s); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudZonesDataSource_basic(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudZonesDataSourceBasicConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_zones.foo"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudZonesDataSource_filter(t *testing.T) {
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudZonesDataSourceFilter,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_zones.foo"),
|
|
||||||
testCheckZoneLength("data.alicloud_zones.foo"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccCheckAlicloudZonesDataSourceFilterIoOptimized,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_zones.foo"),
|
|
||||||
testCheckZoneLength("data.alicloud_zones.foo"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudZonesDataSource_unitRegion(t *testing.T) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
{
|
|
||||||
Config: testAccCheckAlicloudZonesDataSource_unitRegion,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckAlicloudDataSourceID("data.alicloud_zones.foo"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// the zone length changed occasionally
|
|
||||||
// check by range to avoid test case failure
|
|
||||||
func testCheckZoneLength(name string) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
ms := s.RootModule()
|
|
||||||
rs, ok := ms.Resources[name]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
is := rs.Primary
|
|
||||||
if is == nil {
|
|
||||||
return fmt.Errorf("No primary instance: %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
i, err := strconv.Atoi(is.Attributes["zones.#"])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("convert zone length err: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if i <= 0 {
|
|
||||||
return fmt.Errorf("zone length expected greater than 0 got err: %d", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccCheckAlicloudZonesDataSourceBasicConfig = `
|
|
||||||
data "alicloud_zones" "foo" {
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccCheckAlicloudZonesDataSourceFilter = `
|
|
||||||
data "alicloud_zones" "foo" {
|
|
||||||
available_instance_type= "ecs.c2.xlarge"
|
|
||||||
available_resource_creation= "VSwitch"
|
|
||||||
available_disk_category= "cloud_efficiency"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccCheckAlicloudZonesDataSourceFilterIoOptimized = `
|
|
||||||
data "alicloud_zones" "foo" {
|
|
||||||
available_instance_type= "ecs.c2.xlarge"
|
|
||||||
available_resource_creation= "IoOptimized"
|
|
||||||
available_disk_category= "cloud"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccCheckAlicloudZonesDataSource_unitRegion = `
|
|
||||||
provider "alicloud" {
|
|
||||||
alias = "northeast"
|
|
||||||
region = "ap-northeast-1"
|
|
||||||
}
|
|
||||||
|
|
||||||
data "alicloud_zones" "foo" {
|
|
||||||
provider = "alicloud.northeast"
|
|
||||||
available_resource_creation= "VSwitch"
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,52 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import "github.com/denverdino/aliyungo/common"
|
|
||||||
|
|
||||||
const (
|
|
||||||
// common
|
|
||||||
Notfound = "Not found"
|
|
||||||
// ecs
|
|
||||||
InstanceNotfound = "Instance.Notfound"
|
|
||||||
// disk
|
|
||||||
DiskIncorrectStatus = "IncorrectDiskStatus"
|
|
||||||
DiskCreatingSnapshot = "DiskCreatingSnapshot"
|
|
||||||
InstanceLockedForSecurity = "InstanceLockedForSecurity"
|
|
||||||
SystemDiskNotFound = "SystemDiskNotFound"
|
|
||||||
// eip
|
|
||||||
EipIncorrectStatus = "IncorrectEipStatus"
|
|
||||||
InstanceIncorrectStatus = "IncorrectInstanceStatus"
|
|
||||||
HaVipIncorrectStatus = "IncorrectHaVipStatus"
|
|
||||||
// slb
|
|
||||||
LoadBalancerNotFound = "InvalidLoadBalancerId.NotFound"
|
|
||||||
|
|
||||||
// security_group
|
|
||||||
InvalidInstanceIdAlreadyExists = "InvalidInstanceId.AlreadyExists"
|
|
||||||
InvalidSecurityGroupIdNotFound = "InvalidSecurityGroupId.NotFound"
|
|
||||||
SgDependencyViolation = "DependencyViolation"
|
|
||||||
|
|
||||||
//Nat gateway
|
|
||||||
NatGatewayInvalidRegionId = "Invalid.RegionId"
|
|
||||||
DependencyViolationBandwidthPackages = "DependencyViolation.BandwidthPackages"
|
|
||||||
NotFindSnatEntryBySnatId = "NotFindSnatEntryBySnatId"
|
|
||||||
NotFindForwardEntryByForwardId = "NotFindForwardEntryByForwardId"
|
|
||||||
|
|
||||||
// vswitch
|
|
||||||
VswitcInvalidRegionId = "InvalidRegionId.NotFound"
|
|
||||||
|
|
||||||
// ess
|
|
||||||
InvalidScalingGroupIdNotFound = "InvalidScalingGroupId.NotFound"
|
|
||||||
IncorrectScalingConfigurationLifecycleState = "IncorrectScalingConfigurationLifecycleState"
|
|
||||||
|
|
||||||
//unknown Error
|
|
||||||
UnknownError = "UnknownError"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetNotFoundErrorFromString(str string) error {
|
|
||||||
return &common.Error{
|
|
||||||
ErrorResponse: common.ErrorResponse{
|
|
||||||
Code: InstanceNotfound,
|
|
||||||
Message: str,
|
|
||||||
},
|
|
||||||
StatusCode: -1,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
type GroupRuleDirection string
|
|
||||||
|
|
||||||
const (
|
|
||||||
GroupRuleIngress = GroupRuleDirection("ingress")
|
|
||||||
GroupRuleEgress = GroupRuleDirection("egress")
|
|
||||||
)
|
|
||||||
|
|
||||||
type GroupRuleIpProtocol string
|
|
||||||
|
|
||||||
const (
|
|
||||||
GroupRuleTcp = GroupRuleIpProtocol("tcp")
|
|
||||||
GroupRuleUdp = GroupRuleIpProtocol("udp")
|
|
||||||
GroupRuleIcmp = GroupRuleIpProtocol("icmp")
|
|
||||||
GroupRuleGre = GroupRuleIpProtocol("gre")
|
|
||||||
GroupRuleAll = GroupRuleIpProtocol("all")
|
|
||||||
)
|
|
||||||
|
|
||||||
type GroupRuleNicType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
GroupRuleInternet = GroupRuleNicType("internet")
|
|
||||||
GroupRuleIntranet = GroupRuleNicType("intranet")
|
|
||||||
)
|
|
||||||
|
|
||||||
type GroupRulePolicy string
|
|
||||||
|
|
||||||
const (
|
|
||||||
GroupRulePolicyAccept = GroupRulePolicy("accept")
|
|
||||||
GroupRulePolicyDrop = GroupRulePolicy("drop")
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
EcsApiVersion20160314 = "2016-03-14"
|
|
||||||
EcsApiVersion20140526 = "2014-05-26"
|
|
||||||
)
|
|
|
@ -1,164 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/slb"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Listener struct {
|
|
||||||
slb.HTTPListenerType
|
|
||||||
|
|
||||||
InstancePort int
|
|
||||||
LoadBalancerPort int
|
|
||||||
Protocol string
|
|
||||||
//tcp & udp
|
|
||||||
PersistenceTimeout int
|
|
||||||
|
|
||||||
//https
|
|
||||||
SSLCertificateId string
|
|
||||||
|
|
||||||
//tcp
|
|
||||||
HealthCheckType slb.HealthCheckType
|
|
||||||
|
|
||||||
//api interface: http & https is HealthCheckTimeout, tcp & udp is HealthCheckConnectTimeout
|
|
||||||
HealthCheckConnectTimeout int
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListenerErr struct {
|
|
||||||
ErrType string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *ListenerErr) Error() string {
|
|
||||||
return e.ErrType + " " + e.Err.Error()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
HealthCheckErrType = "healthCheckErrType"
|
|
||||||
StickySessionErrType = "stickySessionErrType"
|
|
||||||
CookieTimeOutErrType = "cookieTimeoutErrType"
|
|
||||||
CookieErrType = "cookieErrType"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Takes the result of flatmap.Expand for an array of listeners and
|
|
||||||
// returns ELB API compatible objects
|
|
||||||
func expandListeners(configured []interface{}) ([]*Listener, error) {
|
|
||||||
listeners := make([]*Listener, 0, len(configured))
|
|
||||||
|
|
||||||
// Loop over our configured listeners and create
|
|
||||||
// an array of aws-sdk-go compatabile objects
|
|
||||||
for _, lRaw := range configured {
|
|
||||||
data := lRaw.(map[string]interface{})
|
|
||||||
|
|
||||||
ip := data["instance_port"].(int)
|
|
||||||
lp := data["lb_port"].(int)
|
|
||||||
l := &Listener{
|
|
||||||
InstancePort: ip,
|
|
||||||
LoadBalancerPort: lp,
|
|
||||||
Protocol: data["lb_protocol"].(string),
|
|
||||||
}
|
|
||||||
|
|
||||||
l.Bandwidth = data["bandwidth"].(int)
|
|
||||||
|
|
||||||
if v, ok := data["scheduler"]; ok {
|
|
||||||
l.Scheduler = slb.SchedulerType(v.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["ssl_certificate_id"]; ok {
|
|
||||||
l.SSLCertificateId = v.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["sticky_session"]; ok {
|
|
||||||
l.StickySession = slb.FlagType(v.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["sticky_session_type"]; ok {
|
|
||||||
l.StickySessionType = slb.StickySessionType(v.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["cookie_timeout"]; ok {
|
|
||||||
l.CookieTimeout = v.(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["cookie"]; ok {
|
|
||||||
l.Cookie = v.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["persistence_timeout"]; ok {
|
|
||||||
l.PersistenceTimeout = v.(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check"]; ok {
|
|
||||||
l.HealthCheck = slb.FlagType(v.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check_type"]; ok {
|
|
||||||
l.HealthCheckType = slb.HealthCheckType(v.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check_domain"]; ok {
|
|
||||||
l.HealthCheckDomain = v.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check_uri"]; ok {
|
|
||||||
l.HealthCheckURI = v.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check_connect_port"]; ok {
|
|
||||||
l.HealthCheckConnectPort = v.(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["healthy_threshold"]; ok {
|
|
||||||
l.HealthyThreshold = v.(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["unhealthy_threshold"]; ok {
|
|
||||||
l.UnhealthyThreshold = v.(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check_timeout"]; ok {
|
|
||||||
l.HealthCheckTimeout = v.(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check_interval"]; ok {
|
|
||||||
l.HealthCheckInterval = v.(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := data["health_check_http_code"]; ok {
|
|
||||||
l.HealthCheckHttpCode = slb.HealthCheckHttpCodeType(v.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
var valid bool
|
|
||||||
if l.SSLCertificateId != "" {
|
|
||||||
// validate the protocol is correct
|
|
||||||
for _, p := range []string{"https", "ssl"} {
|
|
||||||
if strings.ToLower(l.Protocol) == p {
|
|
||||||
valid = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
valid = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if valid {
|
|
||||||
listeners = append(listeners, l)
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("[ERR] SLB Listener: ssl_certificate_id may be set only when protocol is 'https' or 'ssl'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return listeners, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func expandBackendServers(list []interface{}) []slb.BackendServerType {
|
|
||||||
result := make([]slb.BackendServerType, 0, len(list))
|
|
||||||
for _, i := range list {
|
|
||||||
if i.(string) != "" {
|
|
||||||
result = append(result, slb.BackendServerType{ServerId: i.(string), Weight: 100})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Tag struct {
|
|
||||||
Key string
|
|
||||||
Value string
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddTagsArgs struct {
|
|
||||||
ResourceId string
|
|
||||||
ResourceType ecs.TagResourceType //image, instance, snapshot or disk
|
|
||||||
RegionId common.Region
|
|
||||||
Tag []Tag
|
|
||||||
}
|
|
||||||
|
|
||||||
type RemoveTagsArgs struct {
|
|
||||||
ResourceId string
|
|
||||||
ResourceType ecs.TagResourceType //image, instance, snapshot or disk
|
|
||||||
RegionId common.Region
|
|
||||||
Tag []Tag
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddTags(client *ecs.Client, args *AddTagsArgs) error {
|
|
||||||
response := ecs.AddTagsResponse{}
|
|
||||||
err := client.Invoke("AddTags", args, &response)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveTags(client *ecs.Client, args *RemoveTagsArgs) error {
|
|
||||||
response := ecs.RemoveTagsResponse{}
|
|
||||||
err := client.Invoke("RemoveTags", args, &response)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/hashicorp/terraform/helper/mutexkv"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Provider returns a schema.Provider for alicloud
|
|
||||||
func Provider() terraform.ResourceProvider {
|
|
||||||
return &schema.Provider{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"access_key": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_ACCESS_KEY", nil),
|
|
||||||
Description: descriptions["access_key"],
|
|
||||||
},
|
|
||||||
"secret_key": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_SECRET_KEY", nil),
|
|
||||||
Description: descriptions["secret_key"],
|
|
||||||
},
|
|
||||||
"region": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_REGION", DEFAULT_REGION),
|
|
||||||
Description: descriptions["region"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DataSourcesMap: map[string]*schema.Resource{
|
|
||||||
|
|
||||||
"alicloud_images": dataSourceAlicloudImages(),
|
|
||||||
"alicloud_regions": dataSourceAlicloudRegions(),
|
|
||||||
"alicloud_zones": dataSourceAlicloudZones(),
|
|
||||||
"alicloud_instance_types": dataSourceAlicloudInstanceTypes(),
|
|
||||||
},
|
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
|
||||||
"alicloud_instance": resourceAliyunInstance(),
|
|
||||||
"alicloud_disk": resourceAliyunDisk(),
|
|
||||||
"alicloud_disk_attachment": resourceAliyunDiskAttachment(),
|
|
||||||
"alicloud_security_group": resourceAliyunSecurityGroup(),
|
|
||||||
"alicloud_security_group_rule": resourceAliyunSecurityGroupRule(),
|
|
||||||
"alicloud_db_instance": resourceAlicloudDBInstance(),
|
|
||||||
"alicloud_ess_scaling_group": resourceAlicloudEssScalingGroup(),
|
|
||||||
"alicloud_ess_scaling_configuration": resourceAlicloudEssScalingConfiguration(),
|
|
||||||
"alicloud_ess_scaling_rule": resourceAlicloudEssScalingRule(),
|
|
||||||
"alicloud_ess_schedule": resourceAlicloudEssSchedule(),
|
|
||||||
"alicloud_vpc": resourceAliyunVpc(),
|
|
||||||
"alicloud_nat_gateway": resourceAliyunNatGateway(),
|
|
||||||
//both subnet and vswith exists,cause compatible old version, and compatible aws habit.
|
|
||||||
"alicloud_subnet": resourceAliyunSubnet(),
|
|
||||||
"alicloud_vswitch": resourceAliyunSubnet(),
|
|
||||||
"alicloud_route_entry": resourceAliyunRouteEntry(),
|
|
||||||
"alicloud_snat_entry": resourceAliyunSnatEntry(),
|
|
||||||
"alicloud_forward_entry": resourceAliyunForwardEntry(),
|
|
||||||
"alicloud_eip": resourceAliyunEip(),
|
|
||||||
"alicloud_eip_association": resourceAliyunEipAssociation(),
|
|
||||||
"alicloud_slb": resourceAliyunSlb(),
|
|
||||||
"alicloud_slb_attachment": resourceAliyunSlbAttachment(),
|
|
||||||
},
|
|
||||||
|
|
||||||
ConfigureFunc: providerConfigure,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
|
||||||
accesskey, ok := d.GetOk("access_key")
|
|
||||||
if !ok {
|
|
||||||
accesskey = os.Getenv("ALICLOUD_ACCESS_KEY")
|
|
||||||
}
|
|
||||||
secretkey, ok := d.GetOk("secret_key")
|
|
||||||
if !ok {
|
|
||||||
secretkey = os.Getenv("ALICLOUD_SECRET_KEY")
|
|
||||||
}
|
|
||||||
region, ok := d.GetOk("region")
|
|
||||||
if !ok {
|
|
||||||
region = os.Getenv("ALICLOUD_REGION")
|
|
||||||
if region == "" {
|
|
||||||
region = DEFAULT_REGION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config := Config{
|
|
||||||
AccessKey: accesskey.(string),
|
|
||||||
SecretKey: secretkey.(string),
|
|
||||||
Region: common.Region(region.(string)),
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := config.Client()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a global MutexKV for use within this plugin.
|
|
||||||
var alicloudMutexKV = mutexkv.NewMutexKV()
|
|
||||||
|
|
||||||
var descriptions map[string]string
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
descriptions = map[string]string{
|
|
||||||
"access_key": "Access key of alicloud",
|
|
||||||
"secret_key": "Secret key of alicloud",
|
|
||||||
"region": "Region of alicloud",
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"fmt"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
var testAccProviders map[string]terraform.ResourceProvider
|
|
||||||
var testAccProvider *schema.Provider
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testAccProvider = Provider().(*schema.Provider)
|
|
||||||
testAccProviders = map[string]terraform.ResourceProvider{
|
|
||||||
"alicloud": testAccProvider,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestProvider(t *testing.T) {
|
|
||||||
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestProvider_impl(t *testing.T) {
|
|
||||||
var _ terraform.ResourceProvider = Provider()
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccPreCheck(t *testing.T) {
|
|
||||||
if v := os.Getenv("ALICLOUD_ACCESS_KEY"); v == "" {
|
|
||||||
t.Fatal("ALICLOUD_ACCESS_KEY must be set for acceptance tests")
|
|
||||||
}
|
|
||||||
if v := os.Getenv("ALICLOUD_SECRET_KEY"); v == "" {
|
|
||||||
t.Fatal("ALICLOUD_SECRET_KEY must be set for acceptance tests")
|
|
||||||
}
|
|
||||||
if v := os.Getenv("ALICLOUD_REGION"); v == "" {
|
|
||||||
log.Println("[INFO] Test: Using cn-beijing as test region")
|
|
||||||
os.Setenv("ALICLOUD_REGION", "cn-beijing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckAlicloudDataSourceID(n string) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Can't find data source: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("data source ID not set")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,550 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/rds"
|
|
||||||
"github.com/hashicorp/terraform/helper/hashcode"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"log"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAlicloudDBInstance() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAlicloudDBInstanceCreate,
|
|
||||||
Read: resourceAlicloudDBInstanceRead,
|
|
||||||
Update: resourceAlicloudDBInstanceUpdate,
|
|
||||||
Delete: resourceAlicloudDBInstanceDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"engine": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ValidateFunc: validateAllowedStringValue([]string{"MySQL", "SQLServer", "PostgreSQL", "PPAS"}),
|
|
||||||
ForceNew: true,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"engine_version": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ValidateFunc: validateAllowedStringValue([]string{"5.5", "5.6", "5.7", "2008r2", "2012", "9.4", "9.3"}),
|
|
||||||
ForceNew: true,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"db_instance_class": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"db_instance_storage": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"instance_charge_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ValidateFunc: validateAllowedStringValue([]string{string(rds.Postpaid), string(rds.Prepaid)}),
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Default: rds.Postpaid,
|
|
||||||
},
|
|
||||||
"period": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
ValidateFunc: validateAllowedIntValue([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 24, 36}),
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Default: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
"zone_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"multi_az": &schema.Schema{
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"db_instance_net_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ValidateFunc: validateAllowedStringValue([]string{string(common.Internet), string(common.Intranet)}),
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"allocate_public_connection": &schema.Schema{
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
"instance_network_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ValidateFunc: validateAllowedStringValue([]string{string(common.VPC), string(common.Classic)}),
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"vswitch_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"master_user_name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"master_user_password": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Optional: true,
|
|
||||||
Sensitive: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"preferred_backup_period": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
// terraform does not support ValidateFunc of TypeList attr
|
|
||||||
// ValidateFunc: validateAllowedStringValue([]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}),
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"preferred_backup_time": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ValidateFunc: validateAllowedStringValue(rds.BACKUP_TIME),
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"backup_retention_period": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
ValidateFunc: validateIntegerInRange(7, 730),
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"security_ips": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
Computed: true,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"port": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"connections": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"connection_string": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"ip_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"ip_address": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"db_mappings": &schema.Schema{
|
|
||||||
Type: schema.TypeSet,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"db_name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"character_set_name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ValidateFunc: validateAllowedStringValue(rds.CHARACTER_SET_NAME),
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"db_description": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Optional: true,
|
|
||||||
Set: resourceAlicloudDatabaseHash,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAlicloudDatabaseHash(v interface{}) int {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
m := v.(map[string]interface{})
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["db_name"].(string)))
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["character_set_name"].(string)))
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["db_description"].(string)))
|
|
||||||
|
|
||||||
return hashcode.String(buf.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAlicloudDBInstanceCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
conn := client.rdsconn
|
|
||||||
|
|
||||||
args, err := buildDBCreateOrderArgs(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := conn.CreateOrder(args)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error creating Alicloud db instance: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceId := resp.DBInstanceId
|
|
||||||
if instanceId == "" {
|
|
||||||
return fmt.Errorf("Error get Alicloud db instance id")
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(instanceId)
|
|
||||||
d.Set("instance_charge_type", d.Get("instance_charge_type"))
|
|
||||||
d.Set("period", d.Get("period"))
|
|
||||||
d.Set("period_type", d.Get("period_type"))
|
|
||||||
|
|
||||||
// wait instance status change from Creating to running
|
|
||||||
if err := conn.WaitForInstance(d.Id(), rds.Running, defaultLongTimeout); err != nil {
|
|
||||||
return fmt.Errorf("WaitForInstance %s got error: %#v", rds.Running, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := modifySecurityIps(d.Id(), d.Get("security_ips"), meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
masterUserName := d.Get("master_user_name").(string)
|
|
||||||
masterUserPwd := d.Get("master_user_password").(string)
|
|
||||||
if masterUserName != "" && masterUserPwd != "" {
|
|
||||||
if err := client.CreateAccountByInfo(d.Id(), masterUserName, masterUserPwd); err != nil {
|
|
||||||
return fmt.Errorf("Create db account %s error: %v", masterUserName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.Get("allocate_public_connection").(bool) {
|
|
||||||
if err := client.AllocateDBPublicConnection(d.Id(), DB_DEFAULT_CONNECT_PORT); err != nil {
|
|
||||||
return fmt.Errorf("Allocate public connection error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resourceAlicloudDBInstanceUpdate(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func modifySecurityIps(id string, ips interface{}, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
ipList := expandStringList(ips.([]interface{}))
|
|
||||||
|
|
||||||
ipstr := strings.Join(ipList[:], COMMA_SEPARATED)
|
|
||||||
// default disable connect from outside
|
|
||||||
if ipstr == "" {
|
|
||||||
ipstr = LOCAL_HOST_IP
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := client.ModifyDBSecurityIps(id, ipstr); err != nil {
|
|
||||||
return fmt.Errorf("Error modify security ips %s: %#v", ipstr, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAlicloudDBInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
conn := client.rdsconn
|
|
||||||
d.Partial(true)
|
|
||||||
|
|
||||||
if d.HasChange("db_mappings") {
|
|
||||||
o, n := d.GetChange("db_mappings")
|
|
||||||
os := o.(*schema.Set)
|
|
||||||
ns := n.(*schema.Set)
|
|
||||||
|
|
||||||
var allDbs []string
|
|
||||||
remove := os.Difference(ns).List()
|
|
||||||
add := ns.Difference(os).List()
|
|
||||||
|
|
||||||
if len(remove) > 0 && len(add) > 0 {
|
|
||||||
return fmt.Errorf("Failure modify database, we neither support create and delete database simultaneous nor modify database attributes.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(remove) > 0 {
|
|
||||||
for _, db := range remove {
|
|
||||||
dbm, _ := db.(map[string]interface{})
|
|
||||||
if err := conn.DeleteDatabase(d.Id(), dbm["db_name"].(string)); err != nil {
|
|
||||||
return fmt.Errorf("Failure delete database %s: %#v", dbm["db_name"].(string), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(add) > 0 {
|
|
||||||
for _, db := range add {
|
|
||||||
dbm, _ := db.(map[string]interface{})
|
|
||||||
dbName := dbm["db_name"].(string)
|
|
||||||
allDbs = append(allDbs, dbName)
|
|
||||||
|
|
||||||
if err := client.CreateDatabaseByInfo(d.Id(), dbName, dbm["character_set_name"].(string), dbm["db_description"].(string)); err != nil {
|
|
||||||
return fmt.Errorf("Failure create database %s: %#v", dbName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := conn.WaitForAllDatabase(d.Id(), allDbs, rds.Running, 600); err != nil {
|
|
||||||
return fmt.Errorf("Failure create database %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if user := d.Get("master_user_name").(string); user != "" {
|
|
||||||
for _, dbName := range allDbs {
|
|
||||||
if err := client.GrantDBPrivilege2Account(d.Id(), user, dbName); err != nil {
|
|
||||||
return fmt.Errorf("Failed to grant database %s readwrite privilege to account %s: %#v", dbName, user, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetPartial("db_mappings")
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("preferred_backup_period") || d.HasChange("preferred_backup_time") || d.HasChange("backup_retention_period") {
|
|
||||||
period := d.Get("preferred_backup_period").([]interface{})
|
|
||||||
periodList := expandStringList(period)
|
|
||||||
time := d.Get("preferred_backup_time").(string)
|
|
||||||
retention := d.Get("backup_retention_period").(int)
|
|
||||||
|
|
||||||
if time == "" || retention == 0 || len(periodList) < 1 {
|
|
||||||
return fmt.Errorf("Both backup_time, backup_period and retention_period are required to set backup policy.")
|
|
||||||
}
|
|
||||||
|
|
||||||
ps := strings.Join(periodList[:], COMMA_SEPARATED)
|
|
||||||
|
|
||||||
if err := client.ConfigDBBackup(d.Id(), time, ps, retention); err != nil {
|
|
||||||
return fmt.Errorf("Error set backup policy: %#v", err)
|
|
||||||
}
|
|
||||||
d.SetPartial("preferred_backup_period")
|
|
||||||
d.SetPartial("preferred_backup_time")
|
|
||||||
d.SetPartial("backup_retention_period")
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("security_ips") {
|
|
||||||
if err := modifySecurityIps(d.Id(), d.Get("security_ips"), meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetPartial("security_ips")
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("db_instance_class") || d.HasChange("db_instance_storage") {
|
|
||||||
co, cn := d.GetChange("db_instance_class")
|
|
||||||
so, sn := d.GetChange("db_instance_storage")
|
|
||||||
classOld := co.(string)
|
|
||||||
classNew := cn.(string)
|
|
||||||
storageOld := so.(int)
|
|
||||||
storageNew := sn.(int)
|
|
||||||
|
|
||||||
// update except the first time, because we will do it in create function
|
|
||||||
if classOld != "" && storageOld != 0 {
|
|
||||||
chargeType := d.Get("instance_charge_type").(string)
|
|
||||||
if chargeType == string(rds.Prepaid) {
|
|
||||||
return fmt.Errorf("Prepaid db instance does not support modify db_instance_class or db_instance_storage")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := client.ModifyDBClassStorage(d.Id(), classNew, strconv.Itoa(storageNew)); err != nil {
|
|
||||||
return fmt.Errorf("Error modify db instance class or storage error: %#v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Partial(false)
|
|
||||||
return resourceAlicloudDBInstanceRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAlicloudDBInstanceRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
conn := client.rdsconn
|
|
||||||
|
|
||||||
instance, err := client.DescribeDBInstanceById(d.Id())
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error Describe DB InstanceAttribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
args := rds.DescribeDatabasesArgs{
|
|
||||||
DBInstanceId: d.Id(),
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := conn.DescribeDatabases(&args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if resp.Databases.Database == nil {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("db_mappings", flattenDatabaseMappings(resp.Databases.Database))
|
|
||||||
|
|
||||||
argn := rds.DescribeDBInstanceNetInfoArgs{
|
|
||||||
DBInstanceId: d.Id(),
|
|
||||||
}
|
|
||||||
|
|
||||||
resn, err := conn.DescribeDBInstanceNetInfo(&argn)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.Set("connections", flattenDBConnections(resn.DBInstanceNetInfos.DBInstanceNetInfo))
|
|
||||||
|
|
||||||
ips, err := client.GetSecurityIps(d.Id())
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Describe DB security ips error: %#v", err)
|
|
||||||
}
|
|
||||||
d.Set("security_ips", ips)
|
|
||||||
|
|
||||||
d.Set("engine", instance.Engine)
|
|
||||||
d.Set("engine_version", instance.EngineVersion)
|
|
||||||
d.Set("db_instance_class", instance.DBInstanceClass)
|
|
||||||
d.Set("port", instance.Port)
|
|
||||||
d.Set("db_instance_storage", instance.DBInstanceStorage)
|
|
||||||
d.Set("zone_id", instance.ZoneId)
|
|
||||||
d.Set("db_instance_net_type", instance.DBInstanceNetType)
|
|
||||||
d.Set("instance_network_type", instance.InstanceNetworkType)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAlicloudDBInstanceDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).rdsconn
|
|
||||||
|
|
||||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
|
||||||
err := conn.DeleteInstance(d.Id())
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return resource.RetryableError(fmt.Errorf("DB Instance in use - trying again while it is deleted."))
|
|
||||||
}
|
|
||||||
|
|
||||||
args := &rds.DescribeDBInstancesArgs{
|
|
||||||
DBInstanceId: d.Id(),
|
|
||||||
}
|
|
||||||
resp, err := conn.DescribeDBInstanceAttribute(args)
|
|
||||||
if err != nil {
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
} else if len(resp.Items.DBInstanceAttribute) < 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.RetryableError(fmt.Errorf("DB in use - trying again while it is deleted."))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildDBCreateOrderArgs(d *schema.ResourceData, meta interface{}) (*rds.CreateOrderArgs, error) {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
args := &rds.CreateOrderArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
// we does not expose this param to user,
|
|
||||||
// because create prepaid instance progress will be stopped when set auto_pay to false,
|
|
||||||
// then could not get instance info, cause timeout error
|
|
||||||
AutoPay: "true",
|
|
||||||
EngineVersion: d.Get("engine_version").(string),
|
|
||||||
Engine: rds.Engine(d.Get("engine").(string)),
|
|
||||||
DBInstanceStorage: d.Get("db_instance_storage").(int),
|
|
||||||
DBInstanceClass: d.Get("db_instance_class").(string),
|
|
||||||
Quantity: DEFAULT_INSTANCE_COUNT,
|
|
||||||
Resource: rds.DefaultResource,
|
|
||||||
}
|
|
||||||
|
|
||||||
bussStr, err := json.Marshal(DefaultBusinessInfo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to translate bussiness info %#v from json to string", DefaultBusinessInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
args.BusinessInfo = string(bussStr)
|
|
||||||
|
|
||||||
zoneId := d.Get("zone_id").(string)
|
|
||||||
args.ZoneId = zoneId
|
|
||||||
|
|
||||||
multiAZ := d.Get("multi_az").(bool)
|
|
||||||
if multiAZ {
|
|
||||||
if zoneId != "" {
|
|
||||||
return nil, fmt.Errorf("You cannot set the ZoneId parameter when the MultiAZ parameter is set to true")
|
|
||||||
}
|
|
||||||
izs, err := client.DescribeMultiIZByRegion()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Get multiAZ id error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(izs) < 1 {
|
|
||||||
return nil, fmt.Errorf("Current region does not support MultiAZ.")
|
|
||||||
}
|
|
||||||
|
|
||||||
args.ZoneId = izs[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
vswitchId := d.Get("vswitch_id").(string)
|
|
||||||
|
|
||||||
networkType := d.Get("instance_network_type").(string)
|
|
||||||
args.InstanceNetworkType = common.NetworkType(networkType)
|
|
||||||
|
|
||||||
if vswitchId != "" {
|
|
||||||
args.VSwitchId = vswitchId
|
|
||||||
|
|
||||||
// check InstanceNetworkType with vswitchId
|
|
||||||
if networkType == string(common.Classic) {
|
|
||||||
return nil, fmt.Errorf("When fill vswitchId, you shold set instance_network_type to VPC")
|
|
||||||
} else if networkType == "" {
|
|
||||||
args.InstanceNetworkType = common.VPC
|
|
||||||
}
|
|
||||||
|
|
||||||
// get vpcId
|
|
||||||
vpcId, err := client.GetVpcIdByVSwitchId(vswitchId)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("VswitchId %s is not valid of current region", vswitchId)
|
|
||||||
}
|
|
||||||
// fill vpcId by vswitchId
|
|
||||||
args.VPCId = vpcId
|
|
||||||
|
|
||||||
// check vswitchId in zone
|
|
||||||
vsw, err := client.QueryVswitchById(vpcId, vswitchId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("VswitchId %s is not valid of current region", vswitchId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if zoneId == "" {
|
|
||||||
args.ZoneId = vsw.ZoneId
|
|
||||||
} else if vsw.ZoneId != zoneId {
|
|
||||||
return nil, fmt.Errorf("VswitchId %s is not belong to the zone %s", vswitchId, zoneId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("db_instance_net_type").(string); v != "" {
|
|
||||||
args.DBInstanceNetType = common.NetType(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
chargeType := d.Get("instance_charge_type").(string)
|
|
||||||
if chargeType != "" {
|
|
||||||
args.PayType = rds.DBPayType(chargeType)
|
|
||||||
} else {
|
|
||||||
args.PayType = rds.Postpaid
|
|
||||||
}
|
|
||||||
|
|
||||||
// if charge type is postpaid, the commodity code must set to bards
|
|
||||||
if chargeType == string(rds.Postpaid) {
|
|
||||||
args.CommodityCode = rds.Bards
|
|
||||||
} else {
|
|
||||||
args.CommodityCode = rds.Rds
|
|
||||||
}
|
|
||||||
|
|
||||||
period := d.Get("period").(int)
|
|
||||||
args.UsedTime, args.TimeType = TransformPeriod2Time(period, chargeType)
|
|
||||||
|
|
||||||
return args, nil
|
|
||||||
}
|
|
|
@ -1,765 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/rds"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_basic(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstanceConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"port",
|
|
||||||
"3306"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"db_instance_storage",
|
|
||||||
"10"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"instance_network_type",
|
|
||||||
"Classic"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"db_instance_net_type",
|
|
||||||
"Intranet"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"engine_version",
|
|
||||||
"5.6"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"engine",
|
|
||||||
"MySQL"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_vpc(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_vpc,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"port",
|
|
||||||
"3306"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"db_instance_storage",
|
|
||||||
"10"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"instance_network_type",
|
|
||||||
"VPC"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"db_instance_net_type",
|
|
||||||
"Intranet"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"engine_version",
|
|
||||||
"5.6"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"engine",
|
|
||||||
"MySQL"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestC2CAlicloudDBInstance_prepaid_order(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_prepaid_order,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"port",
|
|
||||||
"3306"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"db_instance_storage",
|
|
||||||
"10"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"instance_network_type",
|
|
||||||
"VPC"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"db_instance_net_type",
|
|
||||||
"Intranet"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"engine_version",
|
|
||||||
"5.6"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_db_instance.foo",
|
|
||||||
"engine",
|
|
||||||
"MySQL"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_multiIZ(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_multiIZ,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
testAccCheckDBInstanceMultiIZ(&instance),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_database(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_database,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr("alicloud_db_instance.foo", "db_mappings.#", "2"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_database_update,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr("alicloud_db_instance.foo", "db_mappings.#", "3"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_account(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_grantDatabasePrivilege2Account,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr("alicloud_db_instance.foo", "db_mappings.#", "2"),
|
|
||||||
testAccCheckAccountHasPrivilege2Database("alicloud_db_instance.foo", "tester", "foo", "ReadWrite"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_allocatePublicConnection(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_allocatePublicConnection,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr("alicloud_db_instance.foo", "connections.#", "2"),
|
|
||||||
testAccCheckHasPublicConnection("alicloud_db_instance.foo"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_backupPolicy(t *testing.T) {
|
|
||||||
var policies []map[string]interface{}
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_backup,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckBackupPolicyExists(
|
|
||||||
"alicloud_db_instance.foo", policies),
|
|
||||||
testAccCheckKeyValueInMaps(policies, "backup policy", "preferred_backup_period", "Wednesday,Thursday"),
|
|
||||||
testAccCheckKeyValueInMaps(policies, "backup policy", "preferred_backup_time", "00:00Z-01:00Z"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_securityIps(t *testing.T) {
|
|
||||||
var ips []map[string]interface{}
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_securityIps,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckSecurityIpExists(
|
|
||||||
"alicloud_db_instance.foo", ips),
|
|
||||||
testAccCheckKeyValueInMaps(ips, "security ip", "security_ips", "127.0.0.1"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_securityIpsConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckSecurityIpExists(
|
|
||||||
"alicloud_db_instance.foo", ips),
|
|
||||||
testAccCheckKeyValueInMaps(ips, "security ip", "security_ips", "10.168.1.12,100.69.7.112"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDBInstance_upgradeClass(t *testing.T) {
|
|
||||||
var instance rds.DBInstanceAttribute
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_db_instance.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDBInstanceDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_class,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr("alicloud_db_instance.foo", "db_instance_class", "rds.mysql.t1.small"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDBInstance_classUpgrade,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDBInstanceExists(
|
|
||||||
"alicloud_db_instance.foo", &instance),
|
|
||||||
resource.TestCheckResourceAttr("alicloud_db_instance.foo", "db_instance_class", "rds.mysql.s1.small"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckSecurityIpExists(n string, ips []map[string]interface{}) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No DB Instance ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := testAccProvider.Meta().(*AliyunClient).rdsconn
|
|
||||||
args := rds.DescribeDBInstanceIPsArgs{
|
|
||||||
DBInstanceId: rs.Primary.ID,
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := conn.DescribeDBInstanceIPs(&args)
|
|
||||||
log.Printf("[DEBUG] check instance %s security ip %#v", rs.Primary.ID, resp)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
p := resp.Items.DBInstanceIPArray
|
|
||||||
|
|
||||||
if len(p) < 1 {
|
|
||||||
return fmt.Errorf("DB security ip not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
ips = flattenDBSecurityIPs(p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDBInstanceMultiIZ(i *rds.DBInstanceAttribute) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
if !strings.Contains(i.ZoneId, MULTI_IZ_SYMBOL) {
|
|
||||||
return fmt.Errorf("Current region does not support multiIZ.")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckAccountHasPrivilege2Database(n, accountName, dbName, privilege string) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No DB instance ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := testAccProvider.Meta().(*AliyunClient).rdsconn
|
|
||||||
if err := conn.WaitForAccountPrivilege(rs.Primary.ID, accountName, dbName, rds.AccountPrivilege(privilege), 50); err != nil {
|
|
||||||
return fmt.Errorf("Failed to grant database %s privilege to account %s: %v", dbName, accountName, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckHasPublicConnection(n string) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No DB instance ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := testAccProvider.Meta().(*AliyunClient).rdsconn
|
|
||||||
if err := conn.WaitForPublicConnection(rs.Primary.ID, 50); err != nil {
|
|
||||||
return fmt.Errorf("Failed to allocate public connection: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDBInstanceExists(n string, d *rds.DBInstanceAttribute) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No DB Instance ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
attr, err := client.DescribeDBInstanceById(rs.Primary.ID)
|
|
||||||
log.Printf("[DEBUG] check instance %s attribute %#v", rs.Primary.ID, attr)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if attr == nil {
|
|
||||||
return fmt.Errorf("DB Instance not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
*d = *attr
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckBackupPolicyExists(n string, ps []map[string]interface{}) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Backup policy not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No DB Instance ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := testAccProvider.Meta().(*AliyunClient).rdsconn
|
|
||||||
|
|
||||||
args := rds.DescribeBackupPolicyArgs{
|
|
||||||
DBInstanceId: rs.Primary.ID,
|
|
||||||
}
|
|
||||||
resp, err := conn.DescribeBackupPolicy(&args)
|
|
||||||
log.Printf("[DEBUG] check instance %s backup policy %#v", rs.Primary.ID, resp)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var bs []rds.BackupPolicy
|
|
||||||
bs = append(bs, resp.BackupPolicy)
|
|
||||||
ps = flattenDBBackup(bs)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckKeyValueInMaps(ps []map[string]interface{}, propName, key, value string) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
for _, policy := range ps {
|
|
||||||
if policy[key].(string) != value {
|
|
||||||
return fmt.Errorf("DB %s attribute '%s' expected %#v, got %#v", propName, key, value, policy[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDBInstanceDestroy(s *terraform.State) error {
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_db_instance" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ins, err := client.DescribeDBInstanceById(rs.Primary.ID)
|
|
||||||
|
|
||||||
if ins != nil {
|
|
||||||
return fmt.Errorf("Error DB Instance still exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the error is what we want
|
|
||||||
if err != nil {
|
|
||||||
// Verify the error is what we want
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == InstanceNotfound {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccDBInstanceConfig = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_vpc = `
|
|
||||||
data "alicloud_zones" "default" {
|
|
||||||
"available_resource_creation"= "VSwitch"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_vpc" "foo" {
|
|
||||||
name = "tf_test_foo"
|
|
||||||
cidr_block = "172.16.0.0/12"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_vswitch" "foo" {
|
|
||||||
vpc_id = "${alicloud_vpc.foo.id}"
|
|
||||||
cidr_block = "172.16.0.0/21"
|
|
||||||
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
|
|
||||||
vswitch_id = "${alicloud_vswitch.foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const testAccDBInstance_multiIZ = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
multi_az = true
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_prepaid_order = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Prepaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_database = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
|
|
||||||
db_mappings = [
|
|
||||||
{
|
|
||||||
"db_name" = "foo"
|
|
||||||
"character_set_name" = "utf8"
|
|
||||||
"db_description" = "tf"
|
|
||||||
},{
|
|
||||||
"db_name" = "bar"
|
|
||||||
"character_set_name" = "utf8"
|
|
||||||
"db_description" = "tf"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const testAccDBInstance_database_update = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
|
|
||||||
db_mappings = [
|
|
||||||
{
|
|
||||||
"db_name" = "foo"
|
|
||||||
"character_set_name" = "utf8"
|
|
||||||
"db_description" = "tf"
|
|
||||||
},{
|
|
||||||
"db_name" = "bar"
|
|
||||||
"character_set_name" = "utf8"
|
|
||||||
"db_description" = "tf"
|
|
||||||
},{
|
|
||||||
"db_name" = "zzz"
|
|
||||||
"character_set_name" = "utf8"
|
|
||||||
"db_description" = "tf"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_grantDatabasePrivilege2Account = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
|
|
||||||
master_user_name = "tester"
|
|
||||||
master_user_password = "Test12345"
|
|
||||||
|
|
||||||
db_mappings = [
|
|
||||||
{
|
|
||||||
"db_name" = "foo"
|
|
||||||
"character_set_name" = "utf8"
|
|
||||||
"db_description" = "tf"
|
|
||||||
},{
|
|
||||||
"db_name" = "bar"
|
|
||||||
"character_set_name" = "utf8"
|
|
||||||
"db_description" = "tf"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_allocatePublicConnection = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
|
|
||||||
master_user_name = "tester"
|
|
||||||
master_user_password = "Test12345"
|
|
||||||
|
|
||||||
allocate_public_connection = true
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_backup = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
|
|
||||||
preferred_backup_period = ["Wednesday","Thursday"]
|
|
||||||
preferred_backup_time = "00:00Z-01:00Z"
|
|
||||||
backup_retention_period = 9
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_securityIps = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const testAccDBInstance_securityIpsConfig = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
instance_charge_type = "Postpaid"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
|
|
||||||
security_ips = ["10.168.1.12", "100.69.7.112"]
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccDBInstance_class = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.t1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const testAccDBInstance_classUpgrade = `
|
|
||||||
resource "alicloud_db_instance" "foo" {
|
|
||||||
engine = "MySQL"
|
|
||||||
engine_version = "5.6"
|
|
||||||
db_instance_class = "rds.mysql.s1.small"
|
|
||||||
db_instance_storage = "10"
|
|
||||||
db_instance_net_type = "Intranet"
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,247 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAliyunDisk() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAliyunDiskCreate,
|
|
||||||
Read: resourceAliyunDiskRead,
|
|
||||||
Update: resourceAliyunDiskUpdate,
|
|
||||||
Delete: resourceAliyunDiskDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"availability_zone": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ValidateFunc: validateDiskName,
|
|
||||||
},
|
|
||||||
|
|
||||||
"description": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ValidateFunc: validateDiskDescription,
|
|
||||||
},
|
|
||||||
|
|
||||||
"category": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validateDiskCategory,
|
|
||||||
Default: "cloud",
|
|
||||||
},
|
|
||||||
|
|
||||||
"size": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"snapshot_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"status": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"tags": tagsSchema(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunDiskCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
availabilityZone, err := client.DescribeZone(d.Get("availability_zone").(string))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
args := &ecs.CreateDiskArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
ZoneId: availabilityZone.ZoneId,
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := d.GetOk("category"); ok && v.(string) != "" {
|
|
||||||
category := ecs.DiskCategory(v.(string))
|
|
||||||
if err := client.DiskAvailable(availabilityZone, category); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
args.DiskCategory = category
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := d.GetOk("size"); ok {
|
|
||||||
size := v.(int)
|
|
||||||
if args.DiskCategory == ecs.DiskCategoryCloud && (size < 5 || size > 2000) {
|
|
||||||
return fmt.Errorf("the size of cloud disk must between 5 to 2000")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.DiskCategory == ecs.DiskCategoryCloudEfficiency ||
|
|
||||||
args.DiskCategory == ecs.DiskCategoryCloudSSD) && (size < 20 || size > 32768) {
|
|
||||||
return fmt.Errorf("the size of %s disk must between 20 to 32768", args.DiskCategory)
|
|
||||||
}
|
|
||||||
args.Size = size
|
|
||||||
|
|
||||||
d.Set("size", args.Size)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := d.GetOk("snapshot_id"); ok && v.(string) != "" {
|
|
||||||
args.SnapshotId = v.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if args.Size <= 0 && args.SnapshotId == "" {
|
|
||||||
return fmt.Errorf("One of size or snapshot_id is required when specifying an ECS disk.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := d.GetOk("name"); ok && v.(string) != "" {
|
|
||||||
args.DiskName = v.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := d.GetOk("description"); ok && v.(string) != "" {
|
|
||||||
args.Description = v.(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
diskID, err := conn.CreateDisk(args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("CreateDisk got a error: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(diskID)
|
|
||||||
|
|
||||||
return resourceAliyunDiskUpdate(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunDiskRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
disks, _, err := conn.DescribeDisks(&ecs.DescribeDisksArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
DiskIds: []string{d.Id()},
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error DescribeDiskAttribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] DescribeDiskAttribute for instance: %#v", disks)
|
|
||||||
|
|
||||||
if disks == nil || len(disks) <= 0 {
|
|
||||||
return fmt.Errorf("No disks found.")
|
|
||||||
}
|
|
||||||
|
|
||||||
disk := disks[0]
|
|
||||||
d.Set("availability_zone", disk.ZoneId)
|
|
||||||
d.Set("category", disk.Category)
|
|
||||||
d.Set("size", disk.Size)
|
|
||||||
d.Set("status", disk.Status)
|
|
||||||
d.Set("name", disk.DiskName)
|
|
||||||
d.Set("description", disk.Description)
|
|
||||||
d.Set("snapshot_id", disk.SourceSnapshotId)
|
|
||||||
|
|
||||||
tags, _, err := conn.DescribeTags(&ecs.DescribeTagsArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
ResourceType: ecs.TagResourceDisk,
|
|
||||||
ResourceId: d.Id(),
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[DEBUG] DescribeTags for disk got error: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("tags", tagsToMap(tags))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunDiskUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
d.Partial(true)
|
|
||||||
|
|
||||||
if err := setTags(client, ecs.TagResourceDisk, d); err != nil {
|
|
||||||
log.Printf("[DEBUG] Set tags for instance got error: %#v", err)
|
|
||||||
return fmt.Errorf("Set tags for instance got error: %#v", err)
|
|
||||||
} else {
|
|
||||||
d.SetPartial("tags")
|
|
||||||
}
|
|
||||||
attributeUpdate := false
|
|
||||||
args := &ecs.ModifyDiskAttributeArgs{
|
|
||||||
DiskId: d.Id(),
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("name") {
|
|
||||||
d.SetPartial("name")
|
|
||||||
val := d.Get("name").(string)
|
|
||||||
args.DiskName = val
|
|
||||||
|
|
||||||
attributeUpdate = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("description") {
|
|
||||||
d.SetPartial("description")
|
|
||||||
val := d.Get("description").(string)
|
|
||||||
args.Description = val
|
|
||||||
|
|
||||||
attributeUpdate = true
|
|
||||||
}
|
|
||||||
if attributeUpdate {
|
|
||||||
if err := conn.ModifyDiskAttribute(args); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Partial(false)
|
|
||||||
|
|
||||||
return resourceAliyunDiskRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunDiskDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
|
||||||
err := conn.DeleteDisk(d.Id())
|
|
||||||
if err != nil {
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == DiskIncorrectStatus || e.ErrorResponse.Code == DiskCreatingSnapshot {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Disk in use - trying again while it is deleted."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disks, _, descErr := conn.DescribeDisks(&ecs.DescribeDisksArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
DiskIds: []string{d.Id()},
|
|
||||||
})
|
|
||||||
|
|
||||||
if descErr != nil {
|
|
||||||
log.Printf("[ERROR] Delete disk is failed.")
|
|
||||||
return resource.NonRetryableError(descErr)
|
|
||||||
}
|
|
||||||
if disks == nil || len(disks) < 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.RetryableError(fmt.Errorf("Disk in use - trying again while it is deleted."))
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,176 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAliyunDiskAttachment() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAliyunDiskAttachmentCreate,
|
|
||||||
Read: resourceAliyunDiskAttachmentRead,
|
|
||||||
Delete: resourceAliyunDiskAttachmentDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"instance_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"disk_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"device_name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunDiskAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
err := diskAttachment(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(d.Get("disk_id").(string) + ":" + d.Get("instance_id").(string))
|
|
||||||
|
|
||||||
return resourceAliyunDiskAttachmentRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunDiskAttachmentRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
diskId, instanceId, err := getDiskIDAndInstanceID(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
disks, _, err := conn.DescribeDisks(&ecs.DescribeDisksArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
InstanceId: instanceId,
|
|
||||||
DiskIds: []string{diskId},
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error DescribeDiskAttribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] DescribeDiskAttribute for instance: %#v", disks)
|
|
||||||
if disks == nil || len(disks) <= 0 {
|
|
||||||
return fmt.Errorf("No Disks Found.")
|
|
||||||
}
|
|
||||||
|
|
||||||
disk := disks[0]
|
|
||||||
d.Set("instance_id", disk.InstanceId)
|
|
||||||
d.Set("disk_id", disk.DiskId)
|
|
||||||
d.Set("device_name", disk.Device)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunDiskAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
diskID, instanceID, err := getDiskIDAndInstanceID(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
|
||||||
err := conn.DetachDisk(instanceID, diskID)
|
|
||||||
if err != nil {
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == DiskIncorrectStatus || e.ErrorResponse.Code == InstanceLockedForSecurity {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Disk in use - trying again while it detaches"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disks, _, descErr := conn.DescribeDisks(&ecs.DescribeDisksArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
DiskIds: []string{diskID},
|
|
||||||
})
|
|
||||||
|
|
||||||
if descErr != nil {
|
|
||||||
log.Printf("[ERROR] Disk %s is not detached.", diskID)
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, disk := range disks {
|
|
||||||
if disk.Status != ecs.DiskStatusAvailable {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Disk in use - trying again while it is deleted."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func getDiskIDAndInstanceID(d *schema.ResourceData, meta interface{}) (string, string, error) {
|
|
||||||
parts := strings.Split(d.Id(), ":")
|
|
||||||
|
|
||||||
if len(parts) != 2 {
|
|
||||||
return "", "", fmt.Errorf("invalid resource id")
|
|
||||||
}
|
|
||||||
return parts[0], parts[1], nil
|
|
||||||
}
|
|
||||||
func diskAttachment(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
diskID := d.Get("disk_id").(string)
|
|
||||||
instanceID := d.Get("instance_id").(string)
|
|
||||||
|
|
||||||
deviceName := d.Get("device_name").(string)
|
|
||||||
|
|
||||||
args := &ecs.AttachDiskArgs{
|
|
||||||
InstanceId: instanceID,
|
|
||||||
DiskId: diskID,
|
|
||||||
Device: deviceName,
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
|
||||||
err := conn.AttachDisk(args)
|
|
||||||
log.Printf("error : %s", err)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == DiskIncorrectStatus || e.ErrorResponse.Code == InstanceIncorrectStatus {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Disk or Instance status is incorrect - trying again while it attaches"))
|
|
||||||
}
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
disks, _, descErr := conn.DescribeDisks(&ecs.DescribeDisksArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
InstanceId: instanceID,
|
|
||||||
DiskIds: []string{diskID},
|
|
||||||
})
|
|
||||||
|
|
||||||
if descErr != nil {
|
|
||||||
log.Printf("[ERROR] Disk %s is not attached.", diskID)
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if disks == nil || len(disks) <= 0 {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Disk in attaching - trying again while it is attached."))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,155 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudDiskAttachment(t *testing.T) {
|
|
||||||
var i ecs.InstanceAttributesType
|
|
||||||
var v ecs.DiskItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_disk_attachment.disk-att",
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDiskAttachmentDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDiskAttachmentConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckInstanceExists(
|
|
||||||
"alicloud_instance.instance", &i),
|
|
||||||
testAccCheckDiskExists(
|
|
||||||
"alicloud_disk.disk", &v),
|
|
||||||
testAccCheckDiskAttachmentExists(
|
|
||||||
"alicloud_disk_attachment.disk-att", &i, &v),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_disk_attachment.disk-att",
|
|
||||||
"device_name",
|
|
||||||
"/dev/xvdb"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDiskAttachmentExists(n string, instance *ecs.InstanceAttributesType, disk *ecs.DiskItemType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No Disk ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
request := &ecs.DescribeDisksArgs{
|
|
||||||
RegionId: client.Region,
|
|
||||||
DiskIds: []string{rs.Primary.Attributes["disk_id"]},
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.Retry(3*time.Minute, func() *resource.RetryError {
|
|
||||||
response, _, err := conn.DescribeDisks(request)
|
|
||||||
if response != nil {
|
|
||||||
for _, d := range response {
|
|
||||||
if d.Status != ecs.DiskStatusInUse {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Disk is in attaching - trying again while it attaches"))
|
|
||||||
} else if d.InstanceId == instance.InstanceId {
|
|
||||||
// pass
|
|
||||||
*disk = d
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.NonRetryableError(fmt.Errorf("Error finding instance/disk"))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDiskAttachmentDestroy(s *terraform.State) error {
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_disk_attachment" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Try to find the Disk
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
request := &ecs.DescribeDisksArgs{
|
|
||||||
RegionId: client.Region,
|
|
||||||
DiskIds: []string{rs.Primary.ID},
|
|
||||||
}
|
|
||||||
|
|
||||||
response, _, err := conn.DescribeDisks(request)
|
|
||||||
|
|
||||||
for _, disk := range response {
|
|
||||||
if disk.Status != ecs.DiskStatusAvailable {
|
|
||||||
return fmt.Errorf("Error ECS Disk Attachment still exist")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// Verify the error is what we want
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccDiskAttachmentConfig = `
|
|
||||||
resource "alicloud_disk" "disk" {
|
|
||||||
availability_zone = "cn-beijing-a"
|
|
||||||
size = "50"
|
|
||||||
|
|
||||||
tags {
|
|
||||||
Name = "TerraformTest-disk"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_instance" "instance" {
|
|
||||||
image_id = "ubuntu_140405_64_40G_cloudinit_20161115.vhd"
|
|
||||||
instance_type = "ecs.s1.small"
|
|
||||||
availability_zone = "cn-beijing-a"
|
|
||||||
security_groups = ["${alicloud_security_group.group.id}"]
|
|
||||||
instance_name = "hello"
|
|
||||||
internet_charge_type = "PayByBandwidth"
|
|
||||||
io_optimized = "none"
|
|
||||||
|
|
||||||
tags {
|
|
||||||
Name = "TerraformTest-instance"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_disk_attachment" "disk-att" {
|
|
||||||
disk_id = "${alicloud_disk.disk.id}"
|
|
||||||
instance_id = "${alicloud_instance.instance.id}"
|
|
||||||
device_name = "/dev/xvdb"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "group" {
|
|
||||||
name = "terraform-test-group"
|
|
||||||
description = "New security group"
|
|
||||||
}
|
|
||||||
|
|
||||||
`
|
|
|
@ -1,166 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudDisk_basic(t *testing.T) {
|
|
||||||
var v ecs.DiskItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_disk.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDiskDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDiskConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDiskExists(
|
|
||||||
"alicloud_disk.foo", &v),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_disk.foo",
|
|
||||||
"category",
|
|
||||||
"cloud_efficiency"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_disk.foo",
|
|
||||||
"size",
|
|
||||||
"30"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudDisk_withTags(t *testing.T) {
|
|
||||||
var v ecs.DiskItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
//module name
|
|
||||||
IDRefreshName: "alicloud_disk.bar",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckDiskDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccDiskConfigWithTags,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckDiskExists("alicloud_disk.bar", &v),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_disk.bar",
|
|
||||||
"tags.Name",
|
|
||||||
"TerraformTest"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDiskExists(n string, disk *ecs.DiskItemType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No Disk ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
request := &ecs.DescribeDisksArgs{
|
|
||||||
RegionId: client.Region,
|
|
||||||
DiskIds: []string{rs.Primary.ID},
|
|
||||||
}
|
|
||||||
|
|
||||||
response, _, err := conn.DescribeDisks(request)
|
|
||||||
log.Printf("[WARN] disk ids %#v", rs.Primary.ID)
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
if response != nil && len(response) > 0 {
|
|
||||||
*disk = response[0]
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error finding ECS Disk %#v", rs.Primary.ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDiskDestroy(s *terraform.State) error {
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_disk" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find the Disk
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
request := &ecs.DescribeDisksArgs{
|
|
||||||
RegionId: client.Region,
|
|
||||||
DiskIds: []string{rs.Primary.ID},
|
|
||||||
}
|
|
||||||
|
|
||||||
response, _, err := conn.DescribeDisks(request)
|
|
||||||
|
|
||||||
if response != nil && len(response) > 0 {
|
|
||||||
return fmt.Errorf("Error ECS Disk still exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// Verify the error is what we want
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccDiskConfig = `
|
|
||||||
data "alicloud_zones" "default" {
|
|
||||||
"available_disk_category"= "cloud_efficiency"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_disk" "foo" {
|
|
||||||
# cn-beijing
|
|
||||||
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
|
|
||||||
name = "New-disk"
|
|
||||||
description = "Hello ecs disk."
|
|
||||||
category = "cloud_efficiency"
|
|
||||||
size = "30"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const testAccDiskConfigWithTags = `
|
|
||||||
data "alicloud_zones" "default" {
|
|
||||||
"available_disk_category"= "cloud_efficiency"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_disk" "bar" {
|
|
||||||
# cn-beijing
|
|
||||||
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
|
|
||||||
category = "cloud_efficiency"
|
|
||||||
size = "20"
|
|
||||||
tags {
|
|
||||||
Name = "TerraformTest"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,157 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAliyunEip() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAliyunEipCreate,
|
|
||||||
Read: resourceAliyunEipRead,
|
|
||||||
Update: resourceAliyunEipUpdate,
|
|
||||||
Delete: resourceAliyunEipDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"bandwidth": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Default: 5,
|
|
||||||
},
|
|
||||||
"internet_charge_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Default: "PayByBandwidth",
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validateInternetChargeType,
|
|
||||||
},
|
|
||||||
|
|
||||||
"ip_address": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"status": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"instance": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEipCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
args, err := buildAliyunEipArgs(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, allocationID, err := conn.AllocateEipAddress(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(allocationID)
|
|
||||||
|
|
||||||
return resourceAliyunEipRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEipRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
|
|
||||||
eip, err := client.DescribeEipAddress(d.Id())
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error Describe Eip Attribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if eip.InstanceId != "" {
|
|
||||||
d.Set("instance", eip.InstanceId)
|
|
||||||
} else {
|
|
||||||
d.Set("instance", "")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
bandwidth, _ := strconv.Atoi(eip.Bandwidth)
|
|
||||||
d.Set("bandwidth", bandwidth)
|
|
||||||
d.Set("internet_charge_type", eip.InternetChargeType)
|
|
||||||
d.Set("ip_address", eip.IpAddress)
|
|
||||||
d.Set("status", eip.Status)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEipUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
d.Partial(true)
|
|
||||||
|
|
||||||
if d.HasChange("bandwidth") {
|
|
||||||
err := conn.ModifyEipAddressAttribute(d.Id(), d.Get("bandwidth").(int))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetPartial("bandwidth")
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Partial(false)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEipDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
|
||||||
err := conn.ReleaseEipAddress(d.Id())
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == EipIncorrectStatus {
|
|
||||||
return resource.RetryableError(fmt.Errorf("EIP in use - trying again while it is deleted."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args := &ecs.DescribeEipAddressesArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
AllocationId: d.Id(),
|
|
||||||
}
|
|
||||||
|
|
||||||
eips, _, descErr := conn.DescribeEipAddresses(args)
|
|
||||||
if descErr != nil {
|
|
||||||
return resource.NonRetryableError(descErr)
|
|
||||||
} else if eips == nil || len(eips) < 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return resource.RetryableError(fmt.Errorf("EIP in use - trying again while it is deleted."))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildAliyunEipArgs(d *schema.ResourceData, meta interface{}) (*ecs.AllocateEipAddressArgs, error) {
|
|
||||||
|
|
||||||
args := &ecs.AllocateEipAddressArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
Bandwidth: d.Get("bandwidth").(int),
|
|
||||||
InternetChargeType: common.InternetChargeType(d.Get("internet_charge_type").(string)),
|
|
||||||
}
|
|
||||||
|
|
||||||
return args, nil
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAliyunEipAssociation() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAliyunEipAssociationCreate,
|
|
||||||
Read: resourceAliyunEipAssociationRead,
|
|
||||||
Delete: resourceAliyunEipAssociationDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"allocation_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"instance_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEipAssociationCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
allocationId := d.Get("allocation_id").(string)
|
|
||||||
instanceId := d.Get("instance_id").(string)
|
|
||||||
|
|
||||||
if err := conn.AssociateEipAddress(allocationId, instanceId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(allocationId + ":" + instanceId)
|
|
||||||
|
|
||||||
return resourceAliyunEipAssociationRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEipAssociationRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
|
|
||||||
allocationId, instanceId, err := getAllocationIdAndInstanceId(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
eip, err := client.DescribeEipAddress(allocationId)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error Describe Eip Attribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if eip.InstanceId != instanceId {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("instance_id", eip.InstanceId)
|
|
||||||
d.Set("allocation_id", allocationId)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEipAssociationDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
conn := meta.(*AliyunClient).ecsconn
|
|
||||||
|
|
||||||
allocationId, instanceId, err := getAllocationIdAndInstanceId(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
|
||||||
err := conn.UnassociateEipAddress(allocationId, instanceId)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
errCode := e.ErrorResponse.Code
|
|
||||||
if errCode == InstanceIncorrectStatus || errCode == HaVipIncorrectStatus {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Eip in use - trying again while make it unassociated."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args := &ecs.DescribeEipAddressesArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
AllocationId: allocationId,
|
|
||||||
}
|
|
||||||
|
|
||||||
eips, _, descErr := conn.DescribeEipAddresses(args)
|
|
||||||
|
|
||||||
if descErr != nil {
|
|
||||||
return resource.NonRetryableError(descErr)
|
|
||||||
} else if eips == nil || len(eips) < 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, eip := range eips {
|
|
||||||
if eip.Status != ecs.EipStatusAvailable {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Eip in use - trying again while make it unassociated."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAllocationIdAndInstanceId(d *schema.ResourceData, meta interface{}) (string, string, error) {
|
|
||||||
parts := strings.Split(d.Id(), ":")
|
|
||||||
|
|
||||||
if len(parts) != 2 {
|
|
||||||
return "", "", fmt.Errorf("invalid resource id")
|
|
||||||
}
|
|
||||||
return parts[0], parts[1], nil
|
|
||||||
}
|
|
|
@ -1,158 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudEIPAssociation(t *testing.T) {
|
|
||||||
var asso ecs.EipAddressSetType
|
|
||||||
var inst ecs.InstanceAttributesType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_eip_association.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEIPAssociationDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEIPAssociationConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckInstanceExists(
|
|
||||||
"alicloud_instance.instance", &inst),
|
|
||||||
testAccCheckEIPExists(
|
|
||||||
"alicloud_eip.eip", &asso),
|
|
||||||
testAccCheckEIPAssociationExists(
|
|
||||||
"alicloud_eip_association.foo", &inst, &asso),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEIPAssociationExists(n string, instance *ecs.InstanceAttributesType, eip *ecs.EipAddressSetType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No EIP Association ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
return resource.Retry(3*time.Minute, func() *resource.RetryError {
|
|
||||||
d, err := client.DescribeEipAddress(rs.Primary.Attributes["allocation_id"])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d != nil {
|
|
||||||
if d.Status != ecs.EipStatusInUse {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Eip is in associating - trying again while it associates"))
|
|
||||||
} else if d.InstanceId == instance.InstanceId {
|
|
||||||
*eip = *d
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.NonRetryableError(fmt.Errorf("EIP Association not found"))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEIPAssociationDestroy(s *terraform.State) error {
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_eip_association" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No EIP Association ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find the EIP
|
|
||||||
eips, _, err := client.ecsconn.DescribeEipAddresses(&ecs.DescribeEipAddressesArgs{
|
|
||||||
RegionId: client.Region,
|
|
||||||
AllocationId: rs.Primary.Attributes["allocation_id"],
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, eip := range eips {
|
|
||||||
if eip.Status != ecs.EipStatusAvailable {
|
|
||||||
return fmt.Errorf("Error EIP Association still exist")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the error is what we want
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccEIPAssociationConfig = `
|
|
||||||
data "alicloud_zones" "default" {
|
|
||||||
"available_resource_creation"= "VSwitch"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_vpc" "main" {
|
|
||||||
cidr_block = "10.1.0.0/21"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_vswitch" "main" {
|
|
||||||
vpc_id = "${alicloud_vpc.main.id}"
|
|
||||||
cidr_block = "10.1.1.0/24"
|
|
||||||
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
|
|
||||||
depends_on = [
|
|
||||||
"alicloud_vpc.main"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_instance" "instance" {
|
|
||||||
# cn-beijing
|
|
||||||
vswitch_id = "${alicloud_vswitch.main.id}"
|
|
||||||
image_id = "ubuntu_140405_32_40G_cloudinit_20161115.vhd"
|
|
||||||
|
|
||||||
# series II
|
|
||||||
instance_type = "ecs.n1.medium"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
system_disk_category = "cloud_efficiency"
|
|
||||||
|
|
||||||
security_groups = ["${alicloud_security_group.group.id}"]
|
|
||||||
instance_name = "test_foo"
|
|
||||||
|
|
||||||
tags {
|
|
||||||
Name = "TerraformTest-instance"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_eip" "eip" {
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_eip_association" "foo" {
|
|
||||||
allocation_id = "${alicloud_eip.eip.id}"
|
|
||||||
instance_id = "${alicloud_instance.instance.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "group" {
|
|
||||||
name = "terraform-test-group"
|
|
||||||
description = "New security group"
|
|
||||||
vpc_id = "${alicloud_vpc.main.id}"
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,131 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudEIP_basic(t *testing.T) {
|
|
||||||
var eip ecs.EipAddressSetType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_eip.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEIPDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEIPConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEIPExists(
|
|
||||||
"alicloud_eip.foo", &eip),
|
|
||||||
testAccCheckEIPAttributes(&eip),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEIPConfigTwo,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEIPExists(
|
|
||||||
"alicloud_eip.foo", &eip),
|
|
||||||
testAccCheckEIPAttributes(&eip),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_eip.foo",
|
|
||||||
"bandwidth",
|
|
||||||
"10"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEIPExists(n string, eip *ecs.EipAddressSetType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No EIP ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
d, err := client.DescribeEipAddress(rs.Primary.ID)
|
|
||||||
|
|
||||||
log.Printf("[WARN] eip id %#v", rs.Primary.ID)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if d == nil || d.IpAddress == "" {
|
|
||||||
return fmt.Errorf("EIP not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
*eip = *d
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEIPAttributes(eip *ecs.EipAddressSetType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
if eip.IpAddress == "" {
|
|
||||||
return fmt.Errorf("Empty Ip address")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEIPDestroy(s *terraform.State) error {
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_eip" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find the EIP
|
|
||||||
conn := client.ecsconn
|
|
||||||
|
|
||||||
args := &ecs.DescribeEipAddressesArgs{
|
|
||||||
RegionId: client.Region,
|
|
||||||
AllocationId: rs.Primary.ID,
|
|
||||||
}
|
|
||||||
d, _, err := conn.DescribeEipAddresses(args)
|
|
||||||
|
|
||||||
if d != nil && len(d) > 0 {
|
|
||||||
return fmt.Errorf("Error EIP still exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the error is what we want
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccEIPConfig = `
|
|
||||||
resource "alicloud_eip" "foo" {
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEIPConfigTwo = `
|
|
||||||
resource "alicloud_eip" "foo" {
|
|
||||||
bandwidth = "10"
|
|
||||||
internet_charge_type = "PayByBandwidth"
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,320 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ecs"
|
|
||||||
"github.com/denverdino/aliyungo/ess"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAlicloudEssScalingConfiguration() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAliyunEssScalingConfigurationCreate,
|
|
||||||
Read: resourceAliyunEssScalingConfigurationRead,
|
|
||||||
Update: resourceAliyunEssScalingConfigurationUpdate,
|
|
||||||
Delete: resourceAliyunEssScalingConfigurationDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"active": &schema.Schema{
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"enable": &schema.Schema{
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"scaling_group_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"image_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"instance_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"io_optimized": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validateIoOptimized,
|
|
||||||
},
|
|
||||||
"security_group_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"scaling_configuration_name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"internet_charge_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
ForceNew: true,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ValidateFunc: validateInternetChargeType,
|
|
||||||
},
|
|
||||||
"internet_max_bandwidth_in": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"internet_max_bandwidth_out": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validateInternetMaxBandWidthOut,
|
|
||||||
},
|
|
||||||
"system_disk_category": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Computed: true,
|
|
||||||
ValidateFunc: validateAllowedStringValue([]string{
|
|
||||||
string(ecs.DiskCategoryCloud),
|
|
||||||
string(ecs.DiskCategoryCloudSSD),
|
|
||||||
string(ecs.DiskCategoryCloudEfficiency),
|
|
||||||
string(ecs.DiskCategoryEphemeralSSD),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
"data_disk": &schema.Schema{
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"size": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"category": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"snapshot_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"device": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"instance_ids": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
Optional: true,
|
|
||||||
MaxItems: 20,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
args, err := buildAlicloudEssScalingConfigurationArgs(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
essconn := meta.(*AliyunClient).essconn
|
|
||||||
|
|
||||||
scaling, err := essconn.CreateScalingConfiguration(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(d.Get("scaling_group_id").(string) + COLON_SEPARATED + scaling.ScalingConfigurationId)
|
|
||||||
|
|
||||||
return resourceAliyunEssScalingConfigurationUpdate(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingConfigurationUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
if d.HasChange("active") {
|
|
||||||
active := d.Get("active").(bool)
|
|
||||||
if !active {
|
|
||||||
return fmt.Errorf("Please active the scaling configuration directly.")
|
|
||||||
}
|
|
||||||
ids := strings.Split(d.Id(), COLON_SEPARATED)
|
|
||||||
err := client.ActiveScalingConfigurationById(ids[0], ids[1])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Active scaling configuration %s err: %#v", ids[1], err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := enableEssScalingConfiguration(d, meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resourceAliyunEssScalingConfigurationRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func enableEssScalingConfiguration(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
ids := strings.Split(d.Id(), COLON_SEPARATED)
|
|
||||||
|
|
||||||
if d.HasChange("enable") {
|
|
||||||
d.SetPartial("enable")
|
|
||||||
enable := d.Get("enable").(bool)
|
|
||||||
if !enable {
|
|
||||||
err := client.DisableScalingConfigurationById(ids[0])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Disable scaling group %s err: %#v", ids[0], err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
instance_ids := []string{}
|
|
||||||
if d.HasChange("instance_ids") {
|
|
||||||
d.SetPartial("instance_ids")
|
|
||||||
instances := d.Get("instance_ids").([]interface{})
|
|
||||||
instance_ids = expandStringList(instances)
|
|
||||||
}
|
|
||||||
err := client.EnableScalingConfigurationById(ids[0], ids[1], instance_ids)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Enable scaling configuration %s err: %#v", ids[1], err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingConfigurationRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
ids := strings.Split(d.Id(), COLON_SEPARATED)
|
|
||||||
c, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
|
|
||||||
if err != nil {
|
|
||||||
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error Describe ESS scaling configuration Attribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("scaling_group_id", c.ScalingGroupId)
|
|
||||||
d.Set("active", c.LifecycleState == ess.Active)
|
|
||||||
d.Set("image_id", c.ImageId)
|
|
||||||
d.Set("instance_type", c.InstanceType)
|
|
||||||
d.Set("io_optimized", c.IoOptimized)
|
|
||||||
d.Set("security_group_id", c.SecurityGroupId)
|
|
||||||
d.Set("scaling_configuration_name", c.ScalingConfigurationName)
|
|
||||||
d.Set("internet_charge_type", c.InternetChargeType)
|
|
||||||
d.Set("internet_max_bandwidth_in", c.InternetMaxBandwidthIn)
|
|
||||||
d.Set("internet_max_bandwidth_out", c.InternetMaxBandwidthOut)
|
|
||||||
d.Set("system_disk_category", c.SystemDiskCategory)
|
|
||||||
d.Set("data_disk", flattenDataDiskMappings(c.DataDisks.DataDisk))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
|
|
||||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
|
||||||
ids := strings.Split(d.Id(), COLON_SEPARATED)
|
|
||||||
err := client.DeleteScalingConfigurationById(ids[0], ids[1])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == IncorrectScalingConfigurationLifecycleState {
|
|
||||||
return resource.NonRetryableError(
|
|
||||||
fmt.Errorf("Scaling configuration is active - please active another one and trying again."))
|
|
||||||
}
|
|
||||||
if e.ErrorResponse.Code != InvalidScalingGroupIdNotFound {
|
|
||||||
return resource.RetryableError(
|
|
||||||
fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = client.DescribeScalingConfigurationById(ids[0], ids[1])
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.RetryableError(
|
|
||||||
fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildAlicloudEssScalingConfigurationArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingConfigurationArgs, error) {
|
|
||||||
args := &ess.CreateScalingConfigurationArgs{
|
|
||||||
ScalingGroupId: d.Get("scaling_group_id").(string),
|
|
||||||
ImageId: d.Get("image_id").(string),
|
|
||||||
InstanceType: d.Get("instance_type").(string),
|
|
||||||
IoOptimized: ecs.IoOptimized(d.Get("io_optimized").(string)),
|
|
||||||
SecurityGroupId: d.Get("security_group_id").(string),
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("scaling_configuration_name").(string); v != "" {
|
|
||||||
args.ScalingConfigurationName = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("internet_charge_type").(string); v != "" {
|
|
||||||
args.InternetChargeType = common.InternetChargeType(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("internet_max_bandwidth_in").(int); v != 0 {
|
|
||||||
args.InternetMaxBandwidthIn = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("internet_max_bandwidth_out").(int); v != 0 {
|
|
||||||
args.InternetMaxBandwidthOut = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("system_disk_category").(string); v != "" {
|
|
||||||
args.SystemDisk_Category = common.UnderlineString(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
dds, ok := d.GetOk("data_disk")
|
|
||||||
if ok {
|
|
||||||
disks := dds.([]interface{})
|
|
||||||
diskTypes := []ess.DataDiskType{}
|
|
||||||
|
|
||||||
for _, e := range disks {
|
|
||||||
pack := e.(map[string]interface{})
|
|
||||||
disk := ess.DataDiskType{
|
|
||||||
Size: pack["size"].(int),
|
|
||||||
Category: pack["category"].(string),
|
|
||||||
SnapshotId: pack["snapshot_id"].(string),
|
|
||||||
Device: pack["device"].(string),
|
|
||||||
}
|
|
||||||
if v := pack["size"].(int); v != 0 {
|
|
||||||
disk.Size = v
|
|
||||||
}
|
|
||||||
if v := pack["category"].(string); v != "" {
|
|
||||||
disk.Category = v
|
|
||||||
}
|
|
||||||
if v := pack["snapshot_id"].(string); v != "" {
|
|
||||||
disk.SnapshotId = v
|
|
||||||
}
|
|
||||||
if v := pack["device"].(string); v != "" {
|
|
||||||
disk.Device = v
|
|
||||||
}
|
|
||||||
diskTypes = append(diskTypes, disk)
|
|
||||||
}
|
|
||||||
args.DataDisk = diskTypes
|
|
||||||
}
|
|
||||||
|
|
||||||
return args, nil
|
|
||||||
}
|
|
|
@ -1,495 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ess"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"log"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudEssScalingConfiguration_basic(t *testing.T) {
|
|
||||||
var sc ess.ScalingConfigurationItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_configuration.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingConfigurationConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingConfigurationExists(
|
|
||||||
"alicloud_ess_scaling_configuration.foo", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"instance_type",
|
|
||||||
"ecs.s2.large"),
|
|
||||||
resource.TestMatchResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"image_id",
|
|
||||||
regexp.MustCompile("^centos_6")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudEssScalingConfiguration_multiConfig(t *testing.T) {
|
|
||||||
var sc ess.ScalingConfigurationItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_configuration.bar",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingConfiguration_multiConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingConfigurationExists(
|
|
||||||
"alicloud_ess_scaling_configuration.bar", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"active",
|
|
||||||
"false"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"instance_type",
|
|
||||||
"ecs.s2.large"),
|
|
||||||
resource.TestMatchResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"image_id",
|
|
||||||
regexp.MustCompile("^centos_6")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func SkipTestAccAlicloudEssScalingConfiguration_active(t *testing.T) {
|
|
||||||
var sc ess.ScalingConfigurationItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_configuration.bar",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingConfiguration_active,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingConfigurationExists(
|
|
||||||
"alicloud_ess_scaling_configuration.bar", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"active",
|
|
||||||
"true"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"instance_type",
|
|
||||||
"ecs.s2.large"),
|
|
||||||
resource.TestMatchResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"image_id",
|
|
||||||
regexp.MustCompile("^centos_6")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingConfiguration_inActive,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingConfigurationExists(
|
|
||||||
"alicloud_ess_scaling_configuration.bar", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"active",
|
|
||||||
"false"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"instance_type",
|
|
||||||
"ecs.s2.large"),
|
|
||||||
resource.TestMatchResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.bar",
|
|
||||||
"image_id",
|
|
||||||
regexp.MustCompile("^centos_6")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func SkipTestAccAlicloudEssScalingConfiguration_enable(t *testing.T) {
|
|
||||||
var sc ess.ScalingConfigurationItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_configuration.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingConfiguration_enable,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingConfigurationExists(
|
|
||||||
"alicloud_ess_scaling_configuration.foo", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"enable",
|
|
||||||
"true"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"instance_type",
|
|
||||||
"ecs.s2.large"),
|
|
||||||
resource.TestMatchResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"image_id",
|
|
||||||
regexp.MustCompile("^centos_6")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingConfiguration_disable,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingConfigurationExists(
|
|
||||||
"alicloud_ess_scaling_configuration.foo", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"enable",
|
|
||||||
"false"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"instance_type",
|
|
||||||
"ecs.s2.large"),
|
|
||||||
resource.TestMatchResourceAttr(
|
|
||||||
"alicloud_ess_scaling_configuration.foo",
|
|
||||||
"image_id",
|
|
||||||
regexp.MustCompile("^centos_6")),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEssScalingConfigurationExists(n string, d *ess.ScalingConfigurationItemType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No ESS Scaling Configuration ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
|
|
||||||
attr, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
|
|
||||||
log.Printf("[DEBUG] check scaling configuration %s attribute %#v", rs.Primary.ID, attr)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if attr == nil {
|
|
||||||
return fmt.Errorf("Scaling Configuration not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
*d = *attr
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEssScalingConfigurationDestroy(s *terraform.State) error {
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_ess_scaling_configuration" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
|
|
||||||
ins, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
|
|
||||||
|
|
||||||
if ins != nil {
|
|
||||||
return fmt.Errorf("Error ESS scaling configuration still exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the error is what we want
|
|
||||||
if err != nil {
|
|
||||||
// Verify the error is what we want
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == InstanceNotfound {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccEssScalingConfigurationConfig = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingConfiguration_multiConfig = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "bar" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingConfiguration_active = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
active = true
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingConfiguration_inActive = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
active = false
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingConfiguration_enable = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
enable = true
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingConfiguration_disable = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
enable = false
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,209 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ess"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAlicloudEssScalingGroup() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAliyunEssScalingGroupCreate,
|
|
||||||
Read: resourceAliyunEssScalingGroupRead,
|
|
||||||
Update: resourceAliyunEssScalingGroupUpdate,
|
|
||||||
Delete: resourceAliyunEssScalingGroupDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"min_size": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validateIntegerInRange(0, 100),
|
|
||||||
},
|
|
||||||
"max_size": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validateIntegerInRange(0, 100),
|
|
||||||
},
|
|
||||||
"scaling_group_name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"default_cooldown": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Default: 300,
|
|
||||||
Optional: true,
|
|
||||||
ValidateFunc: validateIntegerInRange(0, 86400),
|
|
||||||
},
|
|
||||||
"vswitch_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"removal_policies": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
Optional: true,
|
|
||||||
MaxItems: 2,
|
|
||||||
},
|
|
||||||
"db_instance_ids": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
Optional: true,
|
|
||||||
MaxItems: 3,
|
|
||||||
},
|
|
||||||
"loadbalancer_ids": &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
args, err := buildAlicloudEssScalingGroupArgs(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
essconn := meta.(*AliyunClient).essconn
|
|
||||||
|
|
||||||
scaling, err := essconn.CreateScalingGroup(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(scaling.ScalingGroupId)
|
|
||||||
|
|
||||||
return resourceAliyunEssScalingGroupUpdate(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingGroupRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
|
|
||||||
scaling, err := client.DescribeScalingGroupById(d.Id())
|
|
||||||
if err != nil {
|
|
||||||
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error Describe ESS scaling group Attribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("min_size", scaling.MinSize)
|
|
||||||
d.Set("max_size", scaling.MaxSize)
|
|
||||||
d.Set("scaling_group_name", scaling.ScalingGroupName)
|
|
||||||
d.Set("default_cooldown", scaling.DefaultCooldown)
|
|
||||||
d.Set("removal_policies", scaling.RemovalPolicies)
|
|
||||||
d.Set("db_instance_ids", scaling.DBInstanceIds)
|
|
||||||
d.Set("loadbalancer_ids", scaling.LoadBalancerId)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingGroupUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
conn := meta.(*AliyunClient).essconn
|
|
||||||
args := &ess.ModifyScalingGroupArgs{
|
|
||||||
ScalingGroupId: d.Id(),
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("scaling_group_name") {
|
|
||||||
args.ScalingGroupName = d.Get("scaling_group_name").(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("min_size") {
|
|
||||||
args.MinSize = d.Get("min_size").(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("max_size") {
|
|
||||||
args.MaxSize = d.Get("max_size").(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("default_cooldown") {
|
|
||||||
args.DefaultCooldown = d.Get("default_cooldown").(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("removal_policies") {
|
|
||||||
policyStrings := d.Get("removal_policies").([]interface{})
|
|
||||||
args.RemovalPolicy = expandStringList(policyStrings)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := conn.ModifyScalingGroup(args); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resourceAliyunEssScalingGroupRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingGroupDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
|
|
||||||
return resource.Retry(2*time.Minute, func() *resource.RetryError {
|
|
||||||
err := client.DeleteScalingGroupById(d.Id())
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code != InvalidScalingGroupIdNotFound {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Scaling group in use - trying again while it is deleted."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = client.DescribeScalingGroupById(d.Id())
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.RetryableError(fmt.Errorf("Scaling group in use - trying again while it is deleted."))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildAlicloudEssScalingGroupArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingGroupArgs, error) {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
args := &ess.CreateScalingGroupArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
MinSize: d.Get("min_size").(int),
|
|
||||||
MaxSize: d.Get("max_size").(int),
|
|
||||||
DefaultCooldown: d.Get("default_cooldown").(int),
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("scaling_group_name").(string); v != "" {
|
|
||||||
args.ScalingGroupName = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("vswitch_id").(string); v != "" {
|
|
||||||
args.VSwitchId = v
|
|
||||||
|
|
||||||
// get vpcId
|
|
||||||
vpcId, err := client.GetVpcIdByVSwitchId(v)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("VswitchId %s is not valid of current region", v)
|
|
||||||
}
|
|
||||||
// fill vpcId by vswitchId
|
|
||||||
args.VpcId = vpcId
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
dbs, ok := d.GetOk("db_instance_ids")
|
|
||||||
if ok {
|
|
||||||
dbsStrings := dbs.([]interface{})
|
|
||||||
args.DBInstanceId = expandStringList(dbsStrings)
|
|
||||||
}
|
|
||||||
|
|
||||||
lbs, ok := d.GetOk("loadbalancer_ids")
|
|
||||||
if ok {
|
|
||||||
lbsStrings := lbs.([]interface{})
|
|
||||||
args.LoadBalancerId = strings.Join(expandStringList(lbsStrings), COMMA_SEPARATED)
|
|
||||||
}
|
|
||||||
|
|
||||||
return args, nil
|
|
||||||
}
|
|
|
@ -1,297 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ess"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"log"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudEssScalingGroup_basic(t *testing.T) {
|
|
||||||
var sg ess.ScalingGroupItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_group.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingGroupDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingGroupConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingGroupExists(
|
|
||||||
"alicloud_ess_scaling_group.foo", &sg),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"min_size",
|
|
||||||
"1"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"max_size",
|
|
||||||
"1"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"scaling_group_name",
|
|
||||||
"foo"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"removal_policies.#",
|
|
||||||
"2",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudEssScalingGroup_update(t *testing.T) {
|
|
||||||
var sg ess.ScalingGroupItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_group.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingGroupDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingGroup,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingGroupExists(
|
|
||||||
"alicloud_ess_scaling_group.foo", &sg),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"min_size",
|
|
||||||
"1"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"max_size",
|
|
||||||
"1"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"scaling_group_name",
|
|
||||||
"foo"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"removal_policies.#",
|
|
||||||
"2",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingGroup_update,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingGroupExists(
|
|
||||||
"alicloud_ess_scaling_group.foo", &sg),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"min_size",
|
|
||||||
"2"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"max_size",
|
|
||||||
"2"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"scaling_group_name",
|
|
||||||
"update"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"removal_policies.#",
|
|
||||||
"1",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func SkipTestAccAlicloudEssScalingGroup_vpc(t *testing.T) {
|
|
||||||
var sg ess.ScalingGroupItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_group.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingGroupDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingGroup_vpc,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingGroupExists(
|
|
||||||
"alicloud_ess_scaling_group.foo", &sg),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"min_size",
|
|
||||||
"1"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"max_size",
|
|
||||||
"1"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"scaling_group_name",
|
|
||||||
"foo"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_group.foo",
|
|
||||||
"removal_policies.#",
|
|
||||||
"2",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEssScalingGroupExists(n string, d *ess.ScalingGroupItemType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No ESS Scaling Group ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
attr, err := client.DescribeScalingGroupById(rs.Primary.ID)
|
|
||||||
log.Printf("[DEBUG] check scaling group %s attribute %#v", rs.Primary.ID, attr)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if attr == nil {
|
|
||||||
return fmt.Errorf("Scaling Group not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
*d = *attr
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEssScalingGroupDestroy(s *terraform.State) error {
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_ess_scaling_group" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ins, err := client.DescribeScalingGroupById(rs.Primary.ID)
|
|
||||||
|
|
||||||
if ins != nil {
|
|
||||||
return fmt.Errorf("Error ESS scaling group still exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the error is what we want
|
|
||||||
if err != nil {
|
|
||||||
// Verify the error is what we want
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == InstanceNotfound {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccEssScalingGroupConfig = `
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingGroup = `
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingGroup_update = `
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 2
|
|
||||||
max_size = 2
|
|
||||||
scaling_group_name = "update"
|
|
||||||
removal_policies = ["OldestInstance"]
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const testAccEssScalingGroup_vpc = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
data "alicloud_zones" "default" {
|
|
||||||
"available_disk_category"= "cloud_efficiency"
|
|
||||||
"available_resource_creation"= "VSwitch"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_vpc" "foo" {
|
|
||||||
name = "tf_test_foo"
|
|
||||||
cidr_block = "172.16.0.0/12"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_vswitch" "foo" {
|
|
||||||
vpc_id = "${alicloud_vpc.foo.id}"
|
|
||||||
cidr_block = "172.16.0.0/21"
|
|
||||||
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
vpc_id = "${alicloud_vpc.foo.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "foo" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "foo"
|
|
||||||
default_cooldown = 20
|
|
||||||
vswitch_id = "${alicloud_vswitch.foo.id}"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
|
|
||||||
enable = true
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.n1.medium"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
system_disk_category = "cloud_efficiency"
|
|
||||||
internet_charge_type = "PayByTraffic"
|
|
||||||
internet_max_bandwidth_out = 10
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
`
|
|
|
@ -1,168 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ess"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAlicloudEssScalingRule() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
Create: resourceAliyunEssScalingRuleCreate,
|
|
||||||
Read: resourceAliyunEssScalingRuleRead,
|
|
||||||
Update: resourceAliyunEssScalingRuleUpdate,
|
|
||||||
Delete: resourceAliyunEssScalingRuleDelete,
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"scaling_group_id": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"adjustment_type": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validateAllowedStringValue([]string{string(ess.QuantityChangeInCapacity),
|
|
||||||
string(ess.PercentChangeInCapacity), string(ess.TotalCapacity)}),
|
|
||||||
},
|
|
||||||
"adjustment_value": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"scaling_rule_name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Optional: true,
|
|
||||||
},
|
|
||||||
"ari": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cooldown": &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ValidateFunc: validateIntegerInRange(0, 86400),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingRuleCreate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
args, err := buildAlicloudEssScalingRuleArgs(d, meta)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
essconn := meta.(*AliyunClient).essconn
|
|
||||||
|
|
||||||
rule, err := essconn.CreateScalingRule(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(d.Get("scaling_group_id").(string) + COLON_SEPARATED + rule.ScalingRuleId)
|
|
||||||
|
|
||||||
return resourceAliyunEssScalingRuleUpdate(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingRuleRead(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
ids := strings.Split(d.Id(), COLON_SEPARATED)
|
|
||||||
|
|
||||||
rule, err := client.DescribeScalingRuleById(ids[0], ids[1])
|
|
||||||
if err != nil {
|
|
||||||
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Error Describe ESS scaling rule Attribute: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("scaling_group_id", rule.ScalingGroupId)
|
|
||||||
d.Set("ari", rule.ScalingRuleAri)
|
|
||||||
d.Set("adjustment_type", rule.AdjustmentType)
|
|
||||||
d.Set("adjustment_value", rule.AdjustmentValue)
|
|
||||||
d.Set("scaling_rule_name", rule.ScalingRuleName)
|
|
||||||
d.Set("cooldown", rule.Cooldown)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingRuleDelete(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
client := meta.(*AliyunClient)
|
|
||||||
ids := strings.Split(d.Id(), COLON_SEPARATED)
|
|
||||||
|
|
||||||
return resource.Retry(2*time.Minute, func() *resource.RetryError {
|
|
||||||
err := client.DeleteScalingRuleById(ids[1])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return resource.RetryableError(fmt.Errorf("Scaling rule in use - trying again while it is deleted."))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = client.DescribeScalingRuleById(ids[0], ids[1])
|
|
||||||
if err != nil {
|
|
||||||
if notFoundError(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return resource.NonRetryableError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.RetryableError(fmt.Errorf("Scaling rule in use - trying again while it is deleted."))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAliyunEssScalingRuleUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
||||||
|
|
||||||
conn := meta.(*AliyunClient).essconn
|
|
||||||
ids := strings.Split(d.Id(), COLON_SEPARATED)
|
|
||||||
|
|
||||||
args := &ess.ModifyScalingRuleArgs{
|
|
||||||
ScalingRuleId: ids[1],
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("adjustment_type") {
|
|
||||||
args.AdjustmentType = ess.AdjustmentType(d.Get("adjustment_type").(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("adjustment_value") {
|
|
||||||
args.AdjustmentValue = d.Get("adjustment_value").(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("scaling_rule_name") {
|
|
||||||
args.ScalingRuleName = d.Get("scaling_rule_name").(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("cooldown") {
|
|
||||||
args.Cooldown = d.Get("cooldown").(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := conn.ModifyScalingRule(args); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resourceAliyunEssScalingRuleRead(d, meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildAlicloudEssScalingRuleArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingRuleArgs, error) {
|
|
||||||
args := &ess.CreateScalingRuleArgs{
|
|
||||||
RegionId: getRegion(d, meta),
|
|
||||||
ScalingGroupId: d.Get("scaling_group_id").(string),
|
|
||||||
AdjustmentType: ess.AdjustmentType(d.Get("adjustment_type").(string)),
|
|
||||||
AdjustmentValue: d.Get("adjustment_value").(int),
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("scaling_rule_name").(string); v != "" {
|
|
||||||
args.ScalingRuleName = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if v := d.Get("cooldown").(int); v != 0 {
|
|
||||||
args.Cooldown = v
|
|
||||||
}
|
|
||||||
|
|
||||||
return args, nil
|
|
||||||
}
|
|
|
@ -1,290 +0,0 @@
|
||||||
package alicloud
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/denverdino/aliyungo/common"
|
|
||||||
"github.com/denverdino/aliyungo/ess"
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccAlicloudEssScalingRule_basic(t *testing.T) {
|
|
||||||
var sc ess.ScalingRuleItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_rule.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingRuleDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingRuleConfig,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingRuleExists(
|
|
||||||
"alicloud_ess_scaling_rule.foo", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_rule.foo",
|
|
||||||
"adjustment_type",
|
|
||||||
"TotalCapacity"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_rule.foo",
|
|
||||||
"adjustment_value",
|
|
||||||
"1"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccAlicloudEssScalingRule_update(t *testing.T) {
|
|
||||||
var sc ess.ScalingRuleItemType
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() {
|
|
||||||
testAccPreCheck(t)
|
|
||||||
},
|
|
||||||
|
|
||||||
// module name
|
|
||||||
IDRefreshName: "alicloud_ess_scaling_rule.foo",
|
|
||||||
|
|
||||||
Providers: testAccProviders,
|
|
||||||
CheckDestroy: testAccCheckEssScalingRuleDestroy,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingRule,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingRuleExists(
|
|
||||||
"alicloud_ess_scaling_rule.foo", &sc),
|
|
||||||
testAccCheckEssScalingRuleExists(
|
|
||||||
"alicloud_ess_scaling_rule.foo", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_rule.foo",
|
|
||||||
"adjustment_type",
|
|
||||||
"TotalCapacity"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_rule.foo",
|
|
||||||
"adjustment_value",
|
|
||||||
"1"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccEssScalingRule_update,
|
|
||||||
Check: resource.ComposeTestCheckFunc(
|
|
||||||
testAccCheckEssScalingRuleExists(
|
|
||||||
"alicloud_ess_scaling_rule.foo", &sc),
|
|
||||||
testAccCheckEssScalingRuleExists(
|
|
||||||
"alicloud_ess_scaling_rule.foo", &sc),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_rule.foo",
|
|
||||||
"adjustment_type",
|
|
||||||
"TotalCapacity"),
|
|
||||||
resource.TestCheckResourceAttr(
|
|
||||||
"alicloud_ess_scaling_rule.foo",
|
|
||||||
"adjustment_value",
|
|
||||||
"2"),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEssScalingRuleExists(n string, d *ess.ScalingRuleItemType) resource.TestCheckFunc {
|
|
||||||
return func(s *terraform.State) error {
|
|
||||||
rs, ok := s.RootModule().Resources[n]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Not found: %s", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
|
||||||
return fmt.Errorf("No ESS Scaling Rule ID is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
|
|
||||||
attr, err := client.DescribeScalingRuleById(ids[0], ids[1])
|
|
||||||
log.Printf("[DEBUG] check scaling rule %s attribute %#v", rs.Primary.ID, attr)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if attr == nil {
|
|
||||||
return fmt.Errorf("Scaling rule not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
*d = *attr
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckEssScalingRuleDestroy(s *terraform.State) error {
|
|
||||||
client := testAccProvider.Meta().(*AliyunClient)
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
|
||||||
if rs.Type != "alicloud_ess_scaling_rule" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
|
|
||||||
ins, err := client.DescribeScalingRuleById(ids[0], ids[1])
|
|
||||||
|
|
||||||
if ins != nil {
|
|
||||||
return fmt.Errorf("Error ESS scaling rule still exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the error is what we want
|
|
||||||
if err != nil {
|
|
||||||
// Verify the error is what we want
|
|
||||||
e, _ := err.(*common.Error)
|
|
||||||
if e.ErrorResponse.Code == InstanceNotfound {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAccEssScalingRuleConfig = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "bar" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "bar"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_rule" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
|
|
||||||
adjustment_type = "TotalCapacity"
|
|
||||||
adjustment_value = 1
|
|
||||||
cooldown = 120
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingRule = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "bar" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "bar"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_rule" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
|
|
||||||
adjustment_type = "TotalCapacity"
|
|
||||||
adjustment_value = 1
|
|
||||||
cooldown = 120
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const testAccEssScalingRule_update = `
|
|
||||||
data "alicloud_images" "ecs_image" {
|
|
||||||
most_recent = true
|
|
||||||
name_regex = "^centos_6\\w{1,5}[64].*"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group" "tf_test_foo" {
|
|
||||||
description = "foo"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_security_group_rule" "ssh-in" {
|
|
||||||
type = "ingress"
|
|
||||||
ip_protocol = "tcp"
|
|
||||||
nic_type = "internet"
|
|
||||||
policy = "accept"
|
|
||||||
port_range = "22/22"
|
|
||||||
priority = 1
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
cidr_ip = "0.0.0.0/0"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_group" "bar" {
|
|
||||||
min_size = 1
|
|
||||||
max_size = 1
|
|
||||||
scaling_group_name = "bar"
|
|
||||||
removal_policies = ["OldestInstance", "NewestInstance"]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_configuration" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
|
|
||||||
|
|
||||||
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
|
|
||||||
instance_type = "ecs.s2.large"
|
|
||||||
io_optimized = "optimized"
|
|
||||||
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "alicloud_ess_scaling_rule" "foo" {
|
|
||||||
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
|
|
||||||
adjustment_type = "TotalCapacity"
|
|
||||||
adjustment_value = 2
|
|
||||||
cooldown = 60
|
|
||||||
}
|
|
||||||
`
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue