diff --git a/.travis.yml b/.travis.yml index 9c9210904..e1e60f70e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,7 @@ +#################################################################################### +## NOT FOR UPSTREAM PROPOSAL; INTENDED FOR CI OF AZURE EXAMPLES IN THIS REPO ONLY ## +#################################################################################### + sudo: required services: diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d096a61..7793d2a25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,96 +1,136 @@ -## 0.9.4 (Unreleased) +## 0.9.5 (Unreleased) + +BACKWARDS INCOMPATIBILITIES / NOTES: + +* provider/aws: Users of aws_cloudfront_distributions with custom_origins have been broken due to changes in the AWS API requiring `OriginReadTimeout` being set for updates. This has been fixed and will show as a change in terraform plan / apply. [GH-13367] + +FEATURES: + +* **New Provider:** `gitlab` [GH-13898] + +IMPROVEMENTS: + +* provider/aws: Add support for CustomOrigin timeouts to aws_cloudfront_distribution [GH-13367] +* provider/dnsimple: Add support for import for dnsimple_records [GH-9130] +* provider/triton: Add support for reading provider configuration from `TRITON_*` environment variables in addition to `SDC_*`[GH-14000] + +BUG FIXES: + +* provider/aws: Update aws_ebs_volume when attached [GH-14005] +* provider/aws: Set aws_instance volume_tags to be Computed [GH-14007] +* providers/heroku: Configure buildpacks correctly for both Org Apps and non-org Apps [GH-13990] + +## 0.9.4 (26th April 2017) BACKWARDS INCOMPATIBILITIES / NOTES: * provider/template: Fix invalid MIME formatting in `template_cloudinit_config`. While the change itself is not breaking the data source it may be referenced e.g. in `aws_launch_configuration` and similar resources which are immutable - and the formatting change will therefore trigger recreation [GH-13752] + and the formatting change will therefore trigger recreation ([#13752](https://github.com/hashicorp/terraform/issues/13752)) FEATURES: -* **New Provider:** `opc` - Oracle Public Cloud [GH-13468] -* **New Provider:** `oneandone` [GH-13633] -* **New Data Source:** `aws_ami_ids` [GH-13844] -* **New Data Source:** `aws_ebs_snapshot_ids` [GH-13844] -* **New Data Source:** `aws_kms_alias` [GH-13669] -* **New Data Source:** `aws_kinesis_stream` [GH-13562] -* **New Data Source:** `digitalocean_image` [GH-13787] -* **New Data Source:** `google_compute_network` [GH-12442] -* **New Data Source:** `google_compute_subnetwork` [GH-12442] -* **New Resource:** `local_file` for creating local files (please see the docs for caveats) [GH-12757] -* **New Resource:** `alicloud_ess_scalinggroup` [GH-13731] -* **New Resource:** `alicloud_ess_scalingconfiguration` [GH-13731] -* **New Resource:** `alicloud_ess_scalingrule` [GH-13731] -* **New Resource:** `alicloud_ess_schedule` [GH-13731] -* **New Resource:** `alicloud_snat_entry` [GH-13731] -* **New Resource:** `alicloud_forward_entry` [GH-13731] -* **New Resource:** `aws_cognito_identity_pool` [GH-13783] -* **New Resource:**  `aws_network_interface_attachment` [GH-13861] -* **New Resource:** `github_branch_protection` [GH-10476] -* **New Resource:** `google_bigquery_dataset` [GH-13436] -* **New Interpolation Function:** `coalescelist()` [GH-12537] +* **New Provider:** `opc` - Oracle Public Cloud ([#13468](https://github.com/hashicorp/terraform/issues/13468)) +* **New Provider:** `oneandone` ([#13633](https://github.com/hashicorp/terraform/issues/13633)) +* **New Data Source:** `aws_ami_ids` ([#13844](https://github.com/hashicorp/terraform/issues/13844)] [[#13866](https://github.com/hashicorp/terraform/issues/13866)) +* **New Data Source:** `aws_ebs_snapshot_ids` ([#13844](https://github.com/hashicorp/terraform/issues/13844)] [[#13866](https://github.com/hashicorp/terraform/issues/13866)) +* **New Data Source:** `aws_kms_alias` ([#13669](https://github.com/hashicorp/terraform/issues/13669)) +* **New Data Source:** `aws_kinesis_stream` ([#13562](https://github.com/hashicorp/terraform/issues/13562)) +* **New Data Source:** `digitalocean_image` ([#13787](https://github.com/hashicorp/terraform/issues/13787)) +* **New Data Source:** `google_compute_network` ([#12442](https://github.com/hashicorp/terraform/issues/12442)) +* **New Data Source:** `google_compute_subnetwork` ([#12442](https://github.com/hashicorp/terraform/issues/12442)) +* **New Resource:** `local_file` for creating local files (please see the docs for caveats) ([#12757](https://github.com/hashicorp/terraform/issues/12757)) +* **New Resource:** `alicloud_ess_scalinggroup` ([#13731](https://github.com/hashicorp/terraform/issues/13731)) +* **New Resource:** `alicloud_ess_scalingconfiguration` ([#13731](https://github.com/hashicorp/terraform/issues/13731)) +* **New Resource:** `alicloud_ess_scalingrule` ([#13731](https://github.com/hashicorp/terraform/issues/13731)) +* **New Resource:** `alicloud_ess_schedule` ([#13731](https://github.com/hashicorp/terraform/issues/13731)) +* **New Resource:** `alicloud_snat_entry` ([#13731](https://github.com/hashicorp/terraform/issues/13731)) +* **New Resource:** `alicloud_forward_entry` ([#13731](https://github.com/hashicorp/terraform/issues/13731)) +* **New Resource:** `aws_cognito_identity_pool` ([#13783](https://github.com/hashicorp/terraform/issues/13783)) +* **New Resource:**  `aws_network_interface_attachment` ([#13861](https://github.com/hashicorp/terraform/issues/13861)) +* **New Resource:** `github_branch_protection` ([#10476](https://github.com/hashicorp/terraform/issues/10476)) +* **New Resource:** `google_bigquery_dataset` ([#13436](https://github.com/hashicorp/terraform/issues/13436)) +* **New Resource:** `heroku_space` ([#13921](https://github.com/hashicorp/terraform/issues/13921)) +* **New Resource:** `template_dir` for producing a directory from templates ([#13652](https://github.com/hashicorp/terraform/issues/13652)) +* **New Interpolation Function:** `coalescelist()` ([#12537](https://github.com/hashicorp/terraform/issues/12537)) IMPROVEMENTS: - * helper/schema: Disallow validation+diff suppression on computed fields [GH-13878] - * config: The interpolation function `cidrhost` now accepts a negative host number to count backwards from the end of the range [GH-13765] - * config: New interpolation function `matchkeys` for using values from one list to filter corresponding values from another list using a matching set. [GH-13847] - * state/remote/swift: Support Openstack request logging [GH-13583] - * provider/aws: Add an option to skip getting the supported EC2 platforms [GH-13672] - * provider/aws: Add `name_prefix` support to `aws_cloudwatch_log_group` [GH-13273] - * provider/aws: Add `bucket_prefix` to `aws_s3_bucket` [GH-13274] - * provider/aws: Add replica_source_db to the aws_db_instance datasource [GH-13842] - * provider/aws: Add IPv6 outputs to aws_subnet datasource [GH-13841] - * provider/aws: Exercise SecondaryPrivateIpAddressCount for network interface [GH-10590] - * provider/aws: Expose execution ARN + invoke URL for APIG deployment [GH-13889] - * provider/aws: Expose invoke ARN from Lambda function (for API Gateway) [GH-13890] - * provider/aws: Add tagging support to the 'aws_lambda_function' resource [GH-13873] - * provider/aws: Validate WAF metric names [GH-13885] - * provider/aws: Allow AWS Subnet to change IPv6 CIDR Block without ForceNew [GH-13909] - * provider/azurerm: VM Scale Sets - import support [GH-13464] - * provider/azurerm: Allow Azure China region support [GH-13767] - * provider/digitalocean: Export droplet prices [GH-13720] - * provider/fastly: Add support for GCS logging [GH-13553] - * provider/google: `google_compute_address` and `google_compute_global_address` are now importable [GH-13270] - * provider/google: `google_compute_network` is now importable [GH-13834] - * provider/vault: `vault_generic_secret` resource can now optionally detect drift if it has appropriate access [GH-11776] + + * core: Add a `-reconfigure` flag to the `init` command, to configure a backend while ignoring any saved configuration ([#13825](https://github.com/hashicorp/terraform/issues/13825)) + * helper/schema: Disallow validation+diff suppression on computed fields ([#13878](https://github.com/hashicorp/terraform/issues/13878)) + * config: The interpolation function `cidrhost` now accepts a negative host number to count backwards from the end of the range ([#13765](https://github.com/hashicorp/terraform/issues/13765)) + * config: New interpolation function `matchkeys` for using values from one list to filter corresponding values from another list using a matching set. ([#13847](https://github.com/hashicorp/terraform/issues/13847)) + * state/remote/swift: Support Openstack request logging ([#13583](https://github.com/hashicorp/terraform/issues/13583)) + * provider/aws: Add an option to skip getting the supported EC2 platforms ([#13672](https://github.com/hashicorp/terraform/issues/13672)) + * provider/aws: Add `name_prefix` support to `aws_cloudwatch_log_group` ([#13273](https://github.com/hashicorp/terraform/issues/13273)) + * provider/aws: Add `bucket_prefix` to `aws_s3_bucket` ([#13274](https://github.com/hashicorp/terraform/issues/13274)) + * provider/aws: Add replica_source_db to the aws_db_instance datasource ([#13842](https://github.com/hashicorp/terraform/issues/13842)) + * provider/aws: Add IPv6 outputs to aws_subnet datasource ([#13841](https://github.com/hashicorp/terraform/issues/13841)) + * provider/aws: Exercise SecondaryPrivateIpAddressCount for network interface ([#10590](https://github.com/hashicorp/terraform/issues/10590)) + * provider/aws: Expose execution ARN + invoke URL for APIG deployment ([#13889](https://github.com/hashicorp/terraform/issues/13889)) + * provider/aws: Expose invoke ARN from Lambda function (for API Gateway) ([#13890](https://github.com/hashicorp/terraform/issues/13890)) + * provider/aws: Add tagging support to the 'aws_lambda_function' resource ([#13873](https://github.com/hashicorp/terraform/issues/13873)) + * provider/aws: Validate WAF metric names ([#13885](https://github.com/hashicorp/terraform/issues/13885)) + * provider/aws: Allow AWS Subnet to change IPv6 CIDR Block without ForceNew ([#13909](https://github.com/hashicorp/terraform/issues/13909)) + * provider/aws: Allow filtering of aws_subnet_ids by tags ([#13937](https://github.com/hashicorp/terraform/issues/13937)) + * provider/aws: Support aws_instance and volume tagging on creation ([#13945](https://github.com/hashicorp/terraform/issues/13945)) + * provider/aws: Add network_interface to aws_instance ([#12933](https://github.com/hashicorp/terraform/issues/12933)) + * provider/azurerm: VM Scale Sets - import support ([#13464](https://github.com/hashicorp/terraform/issues/13464)) + * provider/azurerm: Allow Azure China region support ([#13767](https://github.com/hashicorp/terraform/issues/13767)) + * provider/digitalocean: Export droplet prices ([#13720](https://github.com/hashicorp/terraform/issues/13720)) + * provider/fastly: Add support for GCS logging ([#13553](https://github.com/hashicorp/terraform/issues/13553)) + * provider/google: `google_compute_address` and `google_compute_global_address` are now importable ([#13270](https://github.com/hashicorp/terraform/issues/13270)) + * provider/google: `google_compute_network` is now importable ([#13834](https://github.com/hashicorp/terraform/issues/13834)) + * provider/google: add attached_disk field to google_compute_instance ([#13443](https://github.com/hashicorp/terraform/issues/13443)) + * provider/heroku: Set App buildpacks from config ([#13910](https://github.com/hashicorp/terraform/issues/13910)) + * provider/heroku: Create Heroku app in a private space ([#13862](https://github.com/hashicorp/terraform/issues/13862)) + * provider/vault: `vault_generic_secret` resource can now optionally detect drift if it has appropriate access ([#11776](https://github.com/hashicorp/terraform/issues/11776)) BUG FIXES: - * core: Add the close provider/provisioner transformers back [GH-13102] - * core: Fix a crash condition by improving the flatmap.Expand() logic [GH-13541] - * provider/alicloud: Fix create PrePaid instance [GH-13662] - * provider/alicloud: Fix allocate public ip error [GH-13268] - * provider/alicloud: alicloud_security_group_rule: check ptr before use it [GH-13731) - * provider/alicloud: alicloud_instance: fix ecs internet_max_bandwidth_out cannot set zero bug [GH-13731] - * provider/aws: Allow force-destroying `aws_route53_zone` which has trailing dot [GH-12421] - * provider/aws: Allow GovCloud KMS ARNs to pass validation in `kms_key_id` attributes [GH-13699] - * provider/aws: Changing aws_opsworks_instance should ForceNew [GH-13839] - * provider/aws: Fix DB Parameter Group Name [GH-13279] - * provider/aws: Fix issue importing some Security Groups and Rules based on rule structure [GH-13630] - * provider/aws: Fix issue for cross account IAM role with `aws_lambda_permission` [GH-13865] - * provider/aws: Fix WAF IPSet descriptors removal on update [GH-13766] - * provider/aws: Increase default number of retries from 11 to 25 [GH-13673] - * provider/aws: Remove aws_vpc_dhcp_options if not found [GH-13610] - * provider/aws: Remove aws_network_acl_rule if not found [GH-13608] - * provider/aws: Use mutex & retry for WAF change operations [GH-13656] - * provider/aws: Adding support for ipv6 to aws_subnets needs migration [GH-13876] - * provider/azurerm: azurerm_redis_cache resource missing hostname [GH-13650] - * provider/azurerm: Locking around Network Security Group / Subnets [GH-13637] - * provider/azurerm: Locking route table on subnet create/delete [GH-13791] - * provider/azurerm: VM's - fixes a bug where ssh_keys could contain a null entry [GH-13755] - * provider/azurerm: fixing a bug refreshing the `azurerm_redis_cache` [GH-13899] - * provider/fastly: Fix issue with using 0 for `default_ttl` [GH-13648] - * provider/fastly: Add ability to associate a healthcheck to a backend [GH-13539] - * provider/google: Stop setting the id when project creation fails [GH-13644] - * provider/google: Make ports in resource_compute_forwarding_rule ForceNew [GH-13833] - * provider/logentries: Refresh from state when resources not found [GH-13810] - * provider/newrelic: newrelic_alert_condition - `condition_scope` must be `application` or `instance` [GH-12972] - * provider/opc: fixed issue with unqualifying nats [GH-13826] - * provider/opc: Fix instance label if unset [GH-13846] - * provider/openstack: Fix updating Ports [GH-13604] - * provider/rabbitmq: Allow users without tags [GH-13798] + * core: Prevent resource.Retry from adding untracked resources after the timeout: ([#13778](https://github.com/hashicorp/terraform/issues/13778)) + * core: Allow a schema.TypeList to be ForceNew and computed ([#13863](https://github.com/hashicorp/terraform/issues/13863)) + * core: Fix crash when refresh or apply build an invalid graph ([#13665](https://github.com/hashicorp/terraform/issues/13665)) + * core: Add the close provider/provisioner transformers back ([#13102](https://github.com/hashicorp/terraform/issues/13102)) + * core: Fix a crash condition by improving the flatmap.Expand() logic ([#13541](https://github.com/hashicorp/terraform/issues/13541)) + * provider/alicloud: Fix create PrePaid instance ([#13662](https://github.com/hashicorp/terraform/issues/13662)) + * provider/alicloud: Fix allocate public ip error ([#13268](https://github.com/hashicorp/terraform/issues/13268)) + * provider/alicloud: alicloud_security_group_rule: check ptr before use it [[#13731](https://github.com/hashicorp/terraform/issues/13731)) + * provider/alicloud: alicloud_instance: fix ecs internet_max_bandwidth_out cannot set zero bug ([#13731](https://github.com/hashicorp/terraform/issues/13731)) + * provider/aws: Allow force-destroying `aws_route53_zone` which has trailing dot ([#12421](https://github.com/hashicorp/terraform/issues/12421)) + * provider/aws: Allow GovCloud KMS ARNs to pass validation in `kms_key_id` attributes ([#13699](https://github.com/hashicorp/terraform/issues/13699)) + * provider/aws: Changing aws_opsworks_instance should ForceNew ([#13839](https://github.com/hashicorp/terraform/issues/13839)) + * provider/aws: Fix DB Parameter Group Name ([#13279](https://github.com/hashicorp/terraform/issues/13279)) + * provider/aws: Fix issue importing some Security Groups and Rules based on rule structure ([#13630](https://github.com/hashicorp/terraform/issues/13630)) + * provider/aws: Fix issue for cross account IAM role with `aws_lambda_permission` ([#13865](https://github.com/hashicorp/terraform/issues/13865)) + * provider/aws: Fix WAF IPSet descriptors removal on update ([#13766](https://github.com/hashicorp/terraform/issues/13766)) + * provider/aws: Increase default number of retries from 11 to 25 ([#13673](https://github.com/hashicorp/terraform/issues/13673)) + * provider/aws: Remove aws_vpc_dhcp_options if not found ([#13610](https://github.com/hashicorp/terraform/issues/13610)) + * provider/aws: Remove aws_network_acl_rule if not found ([#13608](https://github.com/hashicorp/terraform/issues/13608)) + * provider/aws: Use mutex & retry for WAF change operations ([#13656](https://github.com/hashicorp/terraform/issues/13656)) + * provider/aws: Adding support for ipv6 to aws_subnets needs migration ([#13876](https://github.com/hashicorp/terraform/issues/13876)) + * provider/aws: Fix validation of the `name_prefix` parameter of the `aws_alb` resource ([#13441](https://github.com/hashicorp/terraform/issues/13441)) + * provider/azurerm: azurerm_redis_cache resource missing hostname ([#13650](https://github.com/hashicorp/terraform/issues/13650)) + * provider/azurerm: Locking around Network Security Group / Subnets ([#13637](https://github.com/hashicorp/terraform/issues/13637)) + * provider/azurerm: Locking route table on subnet create/delete ([#13791](https://github.com/hashicorp/terraform/issues/13791)) + * provider/azurerm: VM's - fixes a bug where ssh_keys could contain a null entry ([#13755](https://github.com/hashicorp/terraform/issues/13755)) + * provider/azurerm: VM's - ignoring the case on the `create_option` field during Diff's ([#13933](https://github.com/hashicorp/terraform/issues/13933)) + * provider/azurerm: fixing a bug refreshing the `azurerm_redis_cache` [[#13899](https://github.com/hashicorp/terraform/issues/13899)] + * provider/fastly: Fix issue with using 0 for `default_ttl` ([#13648](https://github.com/hashicorp/terraform/issues/13648)) + * provider/google: Fix panic in GKE provisioning with addons ([#13954](https://github.com/hashicorp/terraform/issues/13954)) + * provider/fastly: Add ability to associate a healthcheck to a backend ([#13539](https://github.com/hashicorp/terraform/issues/13539)) + * provider/google: Stop setting the id when project creation fails ([#13644](https://github.com/hashicorp/terraform/issues/13644)) + * provider/google: Make ports in resource_compute_forwarding_rule ForceNew ([#13833](https://github.com/hashicorp/terraform/issues/13833)) + * provider/google: Validation fixes for forwarding rules ([#13952](https://github.com/hashicorp/terraform/issues/13952)) + * provider/ignition: Internal cache moved to global, instead per provider instance ([#13919](https://github.com/hashicorp/terraform/issues/13919)) + * provider/logentries: Refresh from state when resources not found ([#13810](https://github.com/hashicorp/terraform/issues/13810)) + * provider/newrelic: newrelic_alert_condition - `condition_scope` must be `application` or `instance` ([#12972](https://github.com/hashicorp/terraform/issues/12972)) + * provider/opc: fixed issue with unqualifying nats ([#13826](https://github.com/hashicorp/terraform/issues/13826)) + * provider/opc: Fix instance label if unset ([#13846](https://github.com/hashicorp/terraform/issues/13846)) + * provider/openstack: Fix updating Ports ([#13604](https://github.com/hashicorp/terraform/issues/13604)) + * provider/rabbitmq: Allow users without tags ([#13798](https://github.com/hashicorp/terraform/issues/13798)) ## 0.9.3 (April 12, 2017) @@ -98,111 +138,111 @@ BACKWARDS INCOMPATIBILITIES / NOTES: * provider/aws: Fix a critical bug in `aws_emr_cluster` in order to preserve the ordering of any arguments in `bootstrap_action`. Terraform will now enforce the ordering from the configuration. As a result, `aws_emr_cluster` resources may need to be - recreated, as there is no API to update them in-place [GH-13580] + recreated, as there is no API to update them in-place ([#13580](https://github.com/hashicorp/terraform/issues/13580)) FEATURES: - * **New Resource:** `aws_api_gateway_method_settings` [GH-13542] - * **New Resource:** `aws_api_gateway_stage` [GH-13540] - * **New Resource:** `aws_iam_openid_connect_provider` [GH-13456] - * **New Resource:** `aws_lightsail_static_ip` [GH-13175] - * **New Resource:** `aws_lightsail_static_ip_attachment` [GH-13207] - * **New Resource:** `aws_ses_domain_identity` [GH-13098] - * **New Resource:** `azurerm_managed_disk` [GH-12455] - * **New Resource:** `kubernetes_persistent_volume` [GH-13277] - * **New Resource:** `kubernetes_persistent_volume_claim` [GH-13527] - * **New Resource:** `kubernetes_secret` [GH-12960] - * **New Data Source:** `aws_iam_role` [GH-13213] + * **New Resource:** `aws_api_gateway_method_settings` ([#13542](https://github.com/hashicorp/terraform/issues/13542)) + * **New Resource:** `aws_api_gateway_stage` ([#13540](https://github.com/hashicorp/terraform/issues/13540)) + * **New Resource:** `aws_iam_openid_connect_provider` ([#13456](https://github.com/hashicorp/terraform/issues/13456)) + * **New Resource:** `aws_lightsail_static_ip` ([#13175](https://github.com/hashicorp/terraform/issues/13175)) + * **New Resource:** `aws_lightsail_static_ip_attachment` ([#13207](https://github.com/hashicorp/terraform/issues/13207)) + * **New Resource:** `aws_ses_domain_identity` ([#13098](https://github.com/hashicorp/terraform/issues/13098)) + * **New Resource:** `azurerm_managed_disk` ([#12455](https://github.com/hashicorp/terraform/issues/12455)) + * **New Resource:** `kubernetes_persistent_volume` ([#13277](https://github.com/hashicorp/terraform/issues/13277)) + * **New Resource:** `kubernetes_persistent_volume_claim` ([#13527](https://github.com/hashicorp/terraform/issues/13527)) + * **New Resource:** `kubernetes_secret` ([#12960](https://github.com/hashicorp/terraform/issues/12960)) + * **New Data Source:** `aws_iam_role` ([#13213](https://github.com/hashicorp/terraform/issues/13213)) IMPROVEMENTS: - * core: add `-lock-timeout` option, which will block and retry locks for the given duration [GH-13262] - * core: new `chomp` interpolation function which returns the given string with any trailing newline characters removed [GH-13419] - * backend/remote-state: Add support for assume role extensions to s3 backend [GH-13236] - * backend/remote-state: Filter extra entries from s3 environment listings [GH-13596] - * config: New interpolation functions `basename` and `dirname`, for file path manipulation [GH-13080] - * helper/resource: Allow unknown "pending" states [GH-13099] - * command/hook_ui: Increase max length of state IDs from 20 to 80 [GH-13317] - * provider/aws: Add support to set iam_role_arn on cloudformation Stack [GH-12547] - * provider/aws: Support priority and listener_arn update of alb_listener_rule [GH-13125] - * provider/aws: Deprecate roles in favour of role in iam_instance_profile [GH-13130] - * provider/aws: Make alb_target_group_attachment port optional [GH-13139] - * provider/aws: `aws_api_gateway_domain_name` `certificate_private_key` field marked as sensitive [GH-13147] - * provider/aws: `aws_directory_service_directory` `password` field marked as sensitive [GH-13147] - * provider/aws: `aws_kinesis_firehose_delivery_stream` `password` field marked as sensitive [GH-13147] - * provider/aws: `aws_opsworks_application` `app_source.0.password` & `ssl_configuration.0.private_key` fields marked as sensitive [GH-13147] - * provider/aws: `aws_opsworks_stack` `custom_cookbooks_source.0.password` field marked as sensitive [GH-13147] - * provider/aws: Support the ability to enable / disable ipv6 support in VPC [GH-12527] - * provider/aws: Added API Gateway integration update [GH-13249] - * provider/aws: Add `identifier` | `name_prefix` to RDS resources [GH-13232] - * provider/aws: Validate `aws_ecs_task_definition.container_definitions` [GH-12161] - * provider/aws: Update caller_identity data source [GH-13092] - * provider/aws: `aws_subnet_ids` data source for getting a list of subnet ids matching certain criteria [GH-13188] - * provider/aws: Support ip_address_type for aws_alb [GH-13227] - * provider/aws: Migrate `aws_dms_*` resources away from AWS waiters [GH-13291] - * provider/aws: Add support for treat_missing_data to cloudwatch_metric_alarm [GH-13358] - * provider/aws: Add support for evaluate_low_sample_count_percentiles to cloudwatch_metric_alarm [GH-13371] - * provider/aws: Add `name_prefix` to `aws_alb_target_group` [GH-13442] - * provider/aws: Add support for EMR clusters to aws_appautoscaling_target [GH-13368] - * provider/aws: Add import capabilities to codecommit_repository [GH-13577] - * provider/bitbucket: Improved error handling [GH-13390] - * provider/cloudstack: Do not force a new resource when updating `cloudstack_loadbalancer_rule` members [GH-11786] - * provider/fastly: Add support for Sumologic logging [GH-12541] - * provider/github: Handle the case when issue labels already exist [GH-13182] - * provider/google: Mark `google_container_cluster`'s `client_key` & `password` inside `master_auth` as sensitive [GH-13148] - * provider/google: Add node_pool field in resource_container_cluster [GH-13402] - * provider/kubernetes: Allow defining custom config context [GH-12958] - * provider/openstack: Add support for 'value_specs' options to `openstack_compute_servergroup_v2` [GH-13380] - * provider/statuscake: Add support for StatusCake TriggerRate field [GH-13340] - * provider/triton: Move to joyent/triton-go [GH-13225] - * provisioner/chef: Make sure we add new Chef-Vault clients as clients [GH-13525] + * core: add `-lock-timeout` option, which will block and retry locks for the given duration ([#13262](https://github.com/hashicorp/terraform/issues/13262)) + * core: new `chomp` interpolation function which returns the given string with any trailing newline characters removed ([#13419](https://github.com/hashicorp/terraform/issues/13419)) + * backend/remote-state: Add support for assume role extensions to s3 backend ([#13236](https://github.com/hashicorp/terraform/issues/13236)) + * backend/remote-state: Filter extra entries from s3 environment listings ([#13596](https://github.com/hashicorp/terraform/issues/13596)) + * config: New interpolation functions `basename` and `dirname`, for file path manipulation ([#13080](https://github.com/hashicorp/terraform/issues/13080)) + * helper/resource: Allow unknown "pending" states ([#13099](https://github.com/hashicorp/terraform/issues/13099)) + * command/hook_ui: Increase max length of state IDs from 20 to 80 ([#13317](https://github.com/hashicorp/terraform/issues/13317)) + * provider/aws: Add support to set iam_role_arn on cloudformation Stack ([#12547](https://github.com/hashicorp/terraform/issues/12547)) + * provider/aws: Support priority and listener_arn update of alb_listener_rule ([#13125](https://github.com/hashicorp/terraform/issues/13125)) + * provider/aws: Deprecate roles in favour of role in iam_instance_profile ([#13130](https://github.com/hashicorp/terraform/issues/13130)) + * provider/aws: Make alb_target_group_attachment port optional ([#13139](https://github.com/hashicorp/terraform/issues/13139)) + * provider/aws: `aws_api_gateway_domain_name` `certificate_private_key` field marked as sensitive ([#13147](https://github.com/hashicorp/terraform/issues/13147)) + * provider/aws: `aws_directory_service_directory` `password` field marked as sensitive ([#13147](https://github.com/hashicorp/terraform/issues/13147)) + * provider/aws: `aws_kinesis_firehose_delivery_stream` `password` field marked as sensitive ([#13147](https://github.com/hashicorp/terraform/issues/13147)) + * provider/aws: `aws_opsworks_application` `app_source.0.password` & `ssl_configuration.0.private_key` fields marked as sensitive ([#13147](https://github.com/hashicorp/terraform/issues/13147)) + * provider/aws: `aws_opsworks_stack` `custom_cookbooks_source.0.password` field marked as sensitive ([#13147](https://github.com/hashicorp/terraform/issues/13147)) + * provider/aws: Support the ability to enable / disable ipv6 support in VPC ([#12527](https://github.com/hashicorp/terraform/issues/12527)) + * provider/aws: Added API Gateway integration update ([#13249](https://github.com/hashicorp/terraform/issues/13249)) + * provider/aws: Add `identifier` | `name_prefix` to RDS resources ([#13232](https://github.com/hashicorp/terraform/issues/13232)) + * provider/aws: Validate `aws_ecs_task_definition.container_definitions` ([#12161](https://github.com/hashicorp/terraform/issues/12161)) + * provider/aws: Update caller_identity data source ([#13092](https://github.com/hashicorp/terraform/issues/13092)) + * provider/aws: `aws_subnet_ids` data source for getting a list of subnet ids matching certain criteria ([#13188](https://github.com/hashicorp/terraform/issues/13188)) + * provider/aws: Support ip_address_type for aws_alb ([#13227](https://github.com/hashicorp/terraform/issues/13227)) + * provider/aws: Migrate `aws_dms_*` resources away from AWS waiters ([#13291](https://github.com/hashicorp/terraform/issues/13291)) + * provider/aws: Add support for treat_missing_data to cloudwatch_metric_alarm ([#13358](https://github.com/hashicorp/terraform/issues/13358)) + * provider/aws: Add support for evaluate_low_sample_count_percentiles to cloudwatch_metric_alarm ([#13371](https://github.com/hashicorp/terraform/issues/13371)) + * provider/aws: Add `name_prefix` to `aws_alb_target_group` ([#13442](https://github.com/hashicorp/terraform/issues/13442)) + * provider/aws: Add support for EMR clusters to aws_appautoscaling_target ([#13368](https://github.com/hashicorp/terraform/issues/13368)) + * provider/aws: Add import capabilities to codecommit_repository ([#13577](https://github.com/hashicorp/terraform/issues/13577)) + * provider/bitbucket: Improved error handling ([#13390](https://github.com/hashicorp/terraform/issues/13390)) + * provider/cloudstack: Do not force a new resource when updating `cloudstack_loadbalancer_rule` members ([#11786](https://github.com/hashicorp/terraform/issues/11786)) + * provider/fastly: Add support for Sumologic logging ([#12541](https://github.com/hashicorp/terraform/issues/12541)) + * provider/github: Handle the case when issue labels already exist ([#13182](https://github.com/hashicorp/terraform/issues/13182)) + * provider/google: Mark `google_container_cluster`'s `client_key` & `password` inside `master_auth` as sensitive ([#13148](https://github.com/hashicorp/terraform/issues/13148)) + * provider/google: Add node_pool field in resource_container_cluster ([#13402](https://github.com/hashicorp/terraform/issues/13402)) + * provider/kubernetes: Allow defining custom config context ([#12958](https://github.com/hashicorp/terraform/issues/12958)) + * provider/openstack: Add support for 'value_specs' options to `openstack_compute_servergroup_v2` ([#13380](https://github.com/hashicorp/terraform/issues/13380)) + * provider/statuscake: Add support for StatusCake TriggerRate field ([#13340](https://github.com/hashicorp/terraform/issues/13340)) + * provider/triton: Move to joyent/triton-go ([#13225](https://github.com/hashicorp/terraform/issues/13225)) + * provisioner/chef: Make sure we add new Chef-Vault clients as clients ([#13525](https://github.com/hashicorp/terraform/issues/13525)) BUG FIXES: - * core: Escaped interpolation-like sequences (like `$${foo}`) now permitted in variable defaults [GH-13137] - * core: Fix strange issues with computed values in provider configuration that were worked around with `-input=false` [GH-11264], [GH-13264] - * core: Fix crash when providing nested maps as variable values in a `module` block [GH-13343] - * core: `connection` block attributes are now subject to basic validation of attribute names during validate walk [GH-13400] - * provider/aws: Add Support for maintenance_window and back_window to rds_cluster_instance [GH-13134] - * provider/aws: Increase timeout for AMI registration [GH-13159] - * provider/aws: Increase timeouts for ELB [GH-13161] - * provider/aws: `volume_type` of `aws_elasticsearch_domain.0.ebs_options` marked as `Computed` which prevents spurious diffs [GH-13160] - * provider/aws: Don't set DBName on `aws_db_instance` from snapshot [GH-13140] - * provider/aws: Add DiffSuppression to aws_ecs_service placement_strategies [GH-13220] - * provider/aws: Refresh aws_alb_target_group stickiness on manual updates [GH-13199] - * provider/aws: Preserve default retain_on_delete in cloudfront import [GH-13209] - * provider/aws: Refresh aws_alb_target_group tags [GH-13200] - * provider/aws: Set aws_vpn_connection to recreate when in deleted state [GH-13204] - * provider/aws: Wait for aws_opsworks_instance to be running when it's specified [GH-13218] - * provider/aws: Handle `aws_lambda_function` missing s3 key error [GH-10960] - * provider/aws: Set stickiness to computed in alb_target_group [GH-13278] - * provider/aws: Increase timeout for deploying `cloudfront_distribution` from 40 to 70 mins [GH-13319] - * provider/aws: Increase AMI retry timeouts [GH-13324] - * provider/aws: Increase subnet deletion timeout [GH-13356] - * provider/aws: Increase launch_configuration creation timeout [GH-13357] - * provider/aws: Increase Beanstalk env 'ready' timeout [GH-13359] - * provider/aws: Raise timeout for deleting APIG REST API [GH-13414] - * provider/aws: Raise timeout for attaching/detaching VPN Gateway [GH-13457] - * provider/aws: Recreate opsworks_stack on change of service_role_arn [GH-13325] - * provider/aws: Fix KMS Key reading with Exists method [GH-13348] - * provider/aws: Fix DynamoDB issues about GSIs indexes [GH-13256] - * provider/aws: Fix `aws_s3_bucket` drift detection of logging options [GH-13281] - * provider/aws: Update ElasticTranscoderPreset to have default for MaxFrameRate [GH-13422] - * provider/aws: Fix aws_ami_launch_permission refresh when AMI disappears [GH-13469] - * provider/aws: Add support for updating SSM documents [GH-13491] - * provider/aws: Fix panic on nil route configs [GH-13548] - * provider/azurerm: Network Security Group - ignoring protocol casing at Import time [GH-13153] - * provider/azurerm: Fix crash when importing Local Network Gateways [GH-13261] - * provider/azurerm: Defaulting the value of `duplicate_detection_history_time_window` for `azurerm_servicebus_topic` [GH-13223] - * provider/azurerm: Event Hubs making the Location field idempotent [GH-13570] - * provider/bitbucket: Fixed issue where provider would fail with an "EOF" error on some operations [GH-13390] - * provider/dnsimple: Handle 404 on DNSimple records [GH-13131] - * provider/kubernetes: Use PATCH to update namespace [GH-13114] - * provider/ns1: No splitting answer on SPF records. [GH-13260] - * provider/openstack: Refresh volume_attachment from state if NotFound [GH-13342] - * provider/openstack: Add SOFT_DELETED to delete status [GH-13444] - * provider/profitbricks: Changed output type of ips variable of ip_block ProfitBricks resource [GH-13290] - * provider/template: Fix panic in cloudinit config [GH-13581] + * core: Escaped interpolation-like sequences (like `$${foo}`) now permitted in variable defaults ([#13137](https://github.com/hashicorp/terraform/issues/13137)) + * core: Fix strange issues with computed values in provider configuration that were worked around with `-input=false` ([#11264](https://github.com/hashicorp/terraform/issues/11264)], [[#13264](https://github.com/hashicorp/terraform/issues/13264)) + * core: Fix crash when providing nested maps as variable values in a `module` block ([#13343](https://github.com/hashicorp/terraform/issues/13343)) + * core: `connection` block attributes are now subject to basic validation of attribute names during validate walk ([#13400](https://github.com/hashicorp/terraform/issues/13400)) + * provider/aws: Add Support for maintenance_window and back_window to rds_cluster_instance ([#13134](https://github.com/hashicorp/terraform/issues/13134)) + * provider/aws: Increase timeout for AMI registration ([#13159](https://github.com/hashicorp/terraform/issues/13159)) + * provider/aws: Increase timeouts for ELB ([#13161](https://github.com/hashicorp/terraform/issues/13161)) + * provider/aws: `volume_type` of `aws_elasticsearch_domain.0.ebs_options` marked as `Computed` which prevents spurious diffs ([#13160](https://github.com/hashicorp/terraform/issues/13160)) + * provider/aws: Don't set DBName on `aws_db_instance` from snapshot ([#13140](https://github.com/hashicorp/terraform/issues/13140)) + * provider/aws: Add DiffSuppression to aws_ecs_service placement_strategies ([#13220](https://github.com/hashicorp/terraform/issues/13220)) + * provider/aws: Refresh aws_alb_target_group stickiness on manual updates ([#13199](https://github.com/hashicorp/terraform/issues/13199)) + * provider/aws: Preserve default retain_on_delete in cloudfront import ([#13209](https://github.com/hashicorp/terraform/issues/13209)) + * provider/aws: Refresh aws_alb_target_group tags ([#13200](https://github.com/hashicorp/terraform/issues/13200)) + * provider/aws: Set aws_vpn_connection to recreate when in deleted state ([#13204](https://github.com/hashicorp/terraform/issues/13204)) + * provider/aws: Wait for aws_opsworks_instance to be running when it's specified ([#13218](https://github.com/hashicorp/terraform/issues/13218)) + * provider/aws: Handle `aws_lambda_function` missing s3 key error ([#10960](https://github.com/hashicorp/terraform/issues/10960)) + * provider/aws: Set stickiness to computed in alb_target_group ([#13278](https://github.com/hashicorp/terraform/issues/13278)) + * provider/aws: Increase timeout for deploying `cloudfront_distribution` from 40 to 70 mins ([#13319](https://github.com/hashicorp/terraform/issues/13319)) + * provider/aws: Increase AMI retry timeouts ([#13324](https://github.com/hashicorp/terraform/issues/13324)) + * provider/aws: Increase subnet deletion timeout ([#13356](https://github.com/hashicorp/terraform/issues/13356)) + * provider/aws: Increase launch_configuration creation timeout ([#13357](https://github.com/hashicorp/terraform/issues/13357)) + * provider/aws: Increase Beanstalk env 'ready' timeout ([#13359](https://github.com/hashicorp/terraform/issues/13359)) + * provider/aws: Raise timeout for deleting APIG REST API ([#13414](https://github.com/hashicorp/terraform/issues/13414)) + * provider/aws: Raise timeout for attaching/detaching VPN Gateway ([#13457](https://github.com/hashicorp/terraform/issues/13457)) + * provider/aws: Recreate opsworks_stack on change of service_role_arn ([#13325](https://github.com/hashicorp/terraform/issues/13325)) + * provider/aws: Fix KMS Key reading with Exists method ([#13348](https://github.com/hashicorp/terraform/issues/13348)) + * provider/aws: Fix DynamoDB issues about GSIs indexes ([#13256](https://github.com/hashicorp/terraform/issues/13256)) + * provider/aws: Fix `aws_s3_bucket` drift detection of logging options ([#13281](https://github.com/hashicorp/terraform/issues/13281)) + * provider/aws: Update ElasticTranscoderPreset to have default for MaxFrameRate ([#13422](https://github.com/hashicorp/terraform/issues/13422)) + * provider/aws: Fix aws_ami_launch_permission refresh when AMI disappears ([#13469](https://github.com/hashicorp/terraform/issues/13469)) + * provider/aws: Add support for updating SSM documents ([#13491](https://github.com/hashicorp/terraform/issues/13491)) + * provider/aws: Fix panic on nil route configs ([#13548](https://github.com/hashicorp/terraform/issues/13548)) + * provider/azurerm: Network Security Group - ignoring protocol casing at Import time ([#13153](https://github.com/hashicorp/terraform/issues/13153)) + * provider/azurerm: Fix crash when importing Local Network Gateways ([#13261](https://github.com/hashicorp/terraform/issues/13261)) + * provider/azurerm: Defaulting the value of `duplicate_detection_history_time_window` for `azurerm_servicebus_topic` ([#13223](https://github.com/hashicorp/terraform/issues/13223)) + * provider/azurerm: Event Hubs making the Location field idempotent ([#13570](https://github.com/hashicorp/terraform/issues/13570)) + * provider/bitbucket: Fixed issue where provider would fail with an "EOF" error on some operations ([#13390](https://github.com/hashicorp/terraform/issues/13390)) + * provider/dnsimple: Handle 404 on DNSimple records ([#13131](https://github.com/hashicorp/terraform/issues/13131)) + * provider/kubernetes: Use PATCH to update namespace ([#13114](https://github.com/hashicorp/terraform/issues/13114)) + * provider/ns1: No splitting answer on SPF records. ([#13260](https://github.com/hashicorp/terraform/issues/13260)) + * provider/openstack: Refresh volume_attachment from state if NotFound ([#13342](https://github.com/hashicorp/terraform/issues/13342)) + * provider/openstack: Add SOFT_DELETED to delete status ([#13444](https://github.com/hashicorp/terraform/issues/13444)) + * provider/profitbricks: Changed output type of ips variable of ip_block ProfitBricks resource ([#13290](https://github.com/hashicorp/terraform/issues/13290)) + * provider/template: Fix panic in cloudinit config ([#13581](https://github.com/hashicorp/terraform/issues/13581)) ## 0.9.2 (March 28, 2017) diff --git a/Vagrantfile b/Vagrantfile index f59618e3b..368331868 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -5,7 +5,7 @@ VAGRANTFILE_API_VERSION = "2" # Software version variables -GOVERSION = "1.8" +GOVERSION = "1.8.1" UBUNTUVERSION = "16.04" # CPU and RAM can be adjusted depending on your system diff --git a/backend/local/backend.go b/backend/local/backend.go index 063766b1e..7c715d67a 100644 --- a/backend/local/backend.go +++ b/backend/local/backend.go @@ -170,9 +170,30 @@ func (b *Local) DeleteState(name string) error { } func (b *Local) State(name string) (state.State, error) { + statePath, stateOutPath, backupPath := b.StatePaths(name) + // If we have a backend handling state, defer to that. if b.Backend != nil { - return b.Backend.State(name) + s, err := b.Backend.State(name) + if err != nil { + return nil, err + } + + // make sure we always have a backup state, unless it disabled + if backupPath == "" { + return s, nil + } + + // see if the delegated backend returned a BackupState of its own + if s, ok := s.(*state.BackupState); ok { + return s, nil + } + + s = &state.BackupState{ + Real: s, + Path: backupPath, + } + return s, nil } if s, ok := b.states[name]; ok { @@ -183,8 +204,6 @@ func (b *Local) State(name string) (state.State, error) { return nil, err } - statePath, stateOutPath, backupPath := b.StatePaths(name) - // Otherwise, we need to load the state. var s state.State = &state.LocalState{ Path: statePath, diff --git a/backend/local/backend_apply.go b/backend/local/backend_apply.go index 8fec2019e..9bc41f487 100644 --- a/backend/local/backend_apply.go +++ b/backend/local/backend_apply.go @@ -121,7 +121,7 @@ func (b *Local) opApply( select { case <-ctx.Done(): if b.CLI != nil { - b.CLI.Output("Interrupt received. Gracefully shutting down...") + b.CLI.Output("stopping apply operation...") } // Stop execution diff --git a/backend/local/backend_test.go b/backend/local/backend_test.go index 3b5f1f9bd..a32cbc7d7 100644 --- a/backend/local/backend_test.go +++ b/backend/local/backend_test.go @@ -169,6 +169,11 @@ func TestLocal_addAndRemoveStates(t *testing.T) { // verify it's being called. type testDelegateBackend struct { *Local + + // return a sentinel error on these calls + stateErr bool + statesErr bool + deleteErr bool } var errTestDelegateState = errors.New("State called") @@ -176,22 +181,39 @@ var errTestDelegateStates = errors.New("States called") var errTestDelegateDeleteState = errors.New("Delete called") func (b *testDelegateBackend) State(name string) (state.State, error) { - return nil, errTestDelegateState + if b.stateErr { + return nil, errTestDelegateState + } + s := &state.LocalState{ + Path: "terraform.tfstate", + PathOut: "terraform.tfstate", + } + return s, nil } func (b *testDelegateBackend) States() ([]string, error) { - return nil, errTestDelegateStates + if b.statesErr { + return nil, errTestDelegateStates + } + return []string{"default"}, nil } func (b *testDelegateBackend) DeleteState(name string) error { - return errTestDelegateDeleteState + if b.deleteErr { + return errTestDelegateDeleteState + } + return nil } // verify that the MultiState methods are dispatched to the correct Backend. func TestLocal_multiStateBackend(t *testing.T) { // assign a separate backend where we can read the state b := &Local{ - Backend: &testDelegateBackend{}, + Backend: &testDelegateBackend{ + stateErr: true, + statesErr: true, + deleteErr: true, + }, } if _, err := b.State("test"); err != errTestDelegateState { @@ -205,7 +227,43 @@ func TestLocal_multiStateBackend(t *testing.T) { if err := b.DeleteState("test"); err != errTestDelegateDeleteState { t.Fatal("expected errTestDelegateDeleteState, got:", err) } +} +// verify that a remote state backend is always wrapped in a BackupState +func TestLocal_remoteStateBackup(t *testing.T) { + // assign a separate backend to mock a remote state backend + b := &Local{ + Backend: &testDelegateBackend{}, + } + + s, err := b.State("default") + if err != nil { + t.Fatal(err) + } + + bs, ok := s.(*state.BackupState) + if !ok { + t.Fatal("remote state is not backed up") + } + + if bs.Path != DefaultStateFilename+DefaultBackupExtension { + t.Fatal("bad backup location:", bs.Path) + } + + // do the same with a named state, which should use the local env directories + s, err = b.State("test") + if err != nil { + t.Fatal(err) + } + + bs, ok = s.(*state.BackupState) + if !ok { + t.Fatal("remote state is not backed up") + } + + if bs.Path != filepath.Join(DefaultEnvDir, "test", DefaultStateFilename+DefaultBackupExtension) { + t.Fatal("bad backup location:", bs.Path) + } } // change into a tmp dir and return a deferable func to change back and cleanup diff --git a/builtin/bins/provider-gitlab/main.go b/builtin/bins/provider-gitlab/main.go new file mode 100644 index 000000000..acb94705d --- /dev/null +++ b/builtin/bins/provider-gitlab/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/hashicorp/terraform/builtin/providers/gitlab" + "github.com/hashicorp/terraform/plugin" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: gitlab.Provider, + }) +} diff --git a/builtin/bins/provider-localfile/main.go b/builtin/bins/provider-localfile/main.go index 4a98ecfdd..70494016f 100644 --- a/builtin/bins/provider-localfile/main.go +++ b/builtin/bins/provider-localfile/main.go @@ -1,12 +1,12 @@ package main import ( - "github.com/hashicorp/terraform/builtin/providers/localfile" + "github.com/hashicorp/terraform/builtin/providers/local" "github.com/hashicorp/terraform/plugin" ) func main() { plugin.Serve(&plugin.ServeOpts{ - ProviderFunc: localfile.Provider, + ProviderFunc: local.Provider, }) } diff --git a/builtin/providers/aws/cloudfront_distribution_configuration_structure.go b/builtin/providers/aws/cloudfront_distribution_configuration_structure.go index 489e9883c..a47217647 100644 --- a/builtin/providers/aws/cloudfront_distribution_configuration_structure.go +++ b/builtin/providers/aws/cloudfront_distribution_configuration_structure.go @@ -773,21 +773,31 @@ func originCustomHeaderHash(v interface{}) int { } func expandCustomOriginConfig(m map[string]interface{}) *cloudfront.CustomOriginConfig { - return &cloudfront.CustomOriginConfig{ - OriginProtocolPolicy: aws.String(m["origin_protocol_policy"].(string)), - HTTPPort: aws.Int64(int64(m["http_port"].(int))), - HTTPSPort: aws.Int64(int64(m["https_port"].(int))), - OriginSslProtocols: expandCustomOriginConfigSSL(m["origin_ssl_protocols"].([]interface{})), + + customOrigin := &cloudfront.CustomOriginConfig{ + OriginProtocolPolicy: aws.String(m["origin_protocol_policy"].(string)), + HTTPPort: aws.Int64(int64(m["http_port"].(int))), + HTTPSPort: aws.Int64(int64(m["https_port"].(int))), + OriginSslProtocols: expandCustomOriginConfigSSL(m["origin_ssl_protocols"].([]interface{})), + OriginReadTimeout: aws.Int64(int64(m["origin_read_timeout"].(int))), + OriginKeepaliveTimeout: aws.Int64(int64(m["origin_keepalive_timeout"].(int))), } + + return customOrigin } func flattenCustomOriginConfig(cor *cloudfront.CustomOriginConfig) map[string]interface{} { - return map[string]interface{}{ - "origin_protocol_policy": *cor.OriginProtocolPolicy, - "http_port": int(*cor.HTTPPort), - "https_port": int(*cor.HTTPSPort), - "origin_ssl_protocols": flattenCustomOriginConfigSSL(cor.OriginSslProtocols), + + customOrigin := map[string]interface{}{ + "origin_protocol_policy": *cor.OriginProtocolPolicy, + "http_port": int(*cor.HTTPPort), + "https_port": int(*cor.HTTPSPort), + "origin_ssl_protocols": flattenCustomOriginConfigSSL(cor.OriginSslProtocols), + "origin_read_timeout": int(*cor.OriginReadTimeout), + "origin_keepalive_timeout": int(*cor.OriginKeepaliveTimeout), } + + return customOrigin } // Assemble the hash for the aws_cloudfront_distribution custom_origin_config @@ -801,6 +811,9 @@ func customOriginConfigHash(v interface{}) int { for _, v := range sortInterfaceSlice(m["origin_ssl_protocols"].([]interface{})) { buf.WriteString(fmt.Sprintf("%s-", v.(string))) } + buf.WriteString(fmt.Sprintf("%d-", m["origin_keepalive_timeout"].(int))) + buf.WriteString(fmt.Sprintf("%d-", m["origin_read_timeout"].(int))) + return hashcode.String(buf.String()) } diff --git a/builtin/providers/aws/cloudfront_distribution_configuration_structure_test.go b/builtin/providers/aws/cloudfront_distribution_configuration_structure_test.go index 0092cb8d2..cb594d48e 100644 --- a/builtin/providers/aws/cloudfront_distribution_configuration_structure_test.go +++ b/builtin/providers/aws/cloudfront_distribution_configuration_structure_test.go @@ -117,10 +117,12 @@ func originCustomHeaderConf2() map[string]interface{} { func customOriginConf() map[string]interface{} { return map[string]interface{}{ - "origin_protocol_policy": "http-only", - "http_port": 80, - "https_port": 443, - "origin_ssl_protocols": customOriginSslProtocolsConf(), + "origin_protocol_policy": "http-only", + "http_port": 80, + "https_port": 443, + "origin_ssl_protocols": customOriginSslProtocolsConf(), + "origin_read_timeout": 30, + "origin_keepalive_timeout": 5, } } @@ -785,6 +787,12 @@ func TestCloudFrontStructure_expandCustomOriginConfig(t *testing.T) { if *co.HTTPSPort != 443 { t.Fatalf("Expected HTTPSPort to be 443, got %v", *co.HTTPSPort) } + if *co.OriginReadTimeout != 30 { + t.Fatalf("Expected Origin Read Timeout to be 30, got %v", *co.OriginReadTimeout) + } + if *co.OriginKeepaliveTimeout != 5 { + t.Fatalf("Expected Origin Keepalive Timeout to be 5, got %v", *co.OriginKeepaliveTimeout) + } } func TestCloudFrontStructure_flattenCustomOriginConfig(t *testing.T) { diff --git a/builtin/providers/aws/data_source_aws_ami.go b/builtin/providers/aws/data_source_aws_ami.go index 877069a22..05513c32e 100644 --- a/builtin/providers/aws/data_source_aws_ami.go +++ b/builtin/providers/aws/data_source_aws_ami.go @@ -5,8 +5,6 @@ import ( "fmt" "log" "regexp" - "sort" - "time" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/hashcode" @@ -249,21 +247,9 @@ func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error { return amiDescriptionAttributes(d, image) } -type imageSort []*ec2.Image - -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].CreationDate) - jtime, _ := time.Parse(time.RFC3339, *a[j].CreationDate) - return itime.Unix() < jtime.Unix() -} - // Returns the most recent AMI out of a slice of images. func mostRecentAmi(images []*ec2.Image) *ec2.Image { - sortedImages := images - sort.Sort(imageSort(sortedImages)) - return sortedImages[len(sortedImages)-1] + return sortImages(images)[0] } // populate the numerous fields that the image description returns. diff --git a/builtin/providers/aws/data_source_aws_ami_ids.go b/builtin/providers/aws/data_source_aws_ami_ids.go index bbf4438d5..20df34ac3 100644 --- a/builtin/providers/aws/data_source_aws_ami_ids.go +++ b/builtin/providers/aws/data_source_aws_ami_ids.go @@ -36,10 +36,9 @@ func dataSourceAwsAmiIds() *schema.Resource { }, "tags": dataSourceTagsSchema(), "ids": &schema.Schema{ - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, }, } @@ -101,7 +100,7 @@ func dataSourceAwsAmiIdsRead(d *schema.ResourceData, meta interface{}) error { filteredImages = resp.Images[:] } - for _, image := range filteredImages { + for _, image := range sortImages(filteredImages) { imageIds = append(imageIds, *image.ImageId) } diff --git a/builtin/providers/aws/data_source_aws_ami_ids_test.go b/builtin/providers/aws/data_source_aws_ami_ids_test.go index e2a7ac2d8..52582eaba 100644 --- a/builtin/providers/aws/data_source_aws_ami_ids_test.go +++ b/builtin/providers/aws/data_source_aws_ami_ids_test.go @@ -1,9 +1,11 @@ package aws import ( + "fmt" "testing" "github.com/hashicorp/terraform/helper/resource" + "github.com/satori/uuid" ) func TestAccDataSourceAwsAmiIds_basic(t *testing.T) { @@ -21,6 +23,37 @@ func TestAccDataSourceAwsAmiIds_basic(t *testing.T) { }) } +func TestAccDataSourceAwsAmiIds_sorted(t *testing.T) { + uuid := uuid.NewV4().String() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsAmiIdsConfig_sorted1(uuid), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("aws_ami_from_instance.a", "id"), + resource.TestCheckResourceAttrSet("aws_ami_from_instance.b", "id"), + ), + }, + { + Config: testAccDataSourceAwsAmiIdsConfig_sorted2(uuid), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsEbsSnapshotDataSourceID("data.aws_ami_ids.test"), + resource.TestCheckResourceAttr("data.aws_ami_ids.test", "ids.#", "2"), + resource.TestCheckResourceAttrPair( + "data.aws_ami_ids.test", "ids.0", + "aws_ami_from_instance.b", "id"), + resource.TestCheckResourceAttrPair( + "data.aws_ami_ids.test", "ids.1", + "aws_ami_from_instance.a", "id"), + ), + }, + }, + }) +} + func TestAccDataSourceAwsAmiIds_empty(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -39,15 +72,52 @@ func TestAccDataSourceAwsAmiIds_empty(t *testing.T) { const testAccDataSourceAwsAmiIdsConfig_basic = ` data "aws_ami_ids" "ubuntu" { - owners = ["099720109477"] + owners = ["099720109477"] - filter { - name = "name" - values = ["ubuntu/images/ubuntu-*-*-amd64-server-*"] - } + filter { + name = "name" + values = ["ubuntu/images/ubuntu-*-*-amd64-server-*"] + } } ` +func testAccDataSourceAwsAmiIdsConfig_sorted1(uuid string) string { + return fmt.Sprintf(` +resource "aws_instance" "test" { + ami = "ami-efd0428f" + instance_type = "m3.medium" + + count = 2 +} + +resource "aws_ami_from_instance" "a" { + name = "tf-test-%s-a" + source_instance_id = "${aws_instance.test.*.id[0]}" + snapshot_without_reboot = true +} + +resource "aws_ami_from_instance" "b" { + name = "tf-test-%s-b" + source_instance_id = "${aws_instance.test.*.id[1]}" + snapshot_without_reboot = true + + // We want to ensure that 'aws_ami_from_instance.a.creation_date' is less + // than 'aws_ami_from_instance.b.creation_date' so that we can ensure that + // the images are being sorted correctly. + depends_on = ["aws_ami_from_instance.a"] +} +`, uuid, uuid) +} + +func testAccDataSourceAwsAmiIdsConfig_sorted2(uuid string) string { + return testAccDataSourceAwsAmiIdsConfig_sorted1(uuid) + fmt.Sprintf(` +data "aws_ami_ids" "test" { + owners = ["self"] + name_regex = "^tf-test-%s-" +} +`, uuid) +} + const testAccDataSourceAwsAmiIdsConfig_empty = ` data "aws_ami_ids" "empty" { filter { diff --git a/builtin/providers/aws/data_source_aws_ebs_snapshot.go b/builtin/providers/aws/data_source_aws_ebs_snapshot.go index b16f61f22..a36334723 100644 --- a/builtin/providers/aws/data_source_aws_ebs_snapshot.go +++ b/builtin/providers/aws/data_source_aws_ebs_snapshot.go @@ -3,7 +3,6 @@ package aws import ( "fmt" "log" - "sort" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/schema" @@ -138,20 +137,8 @@ func dataSourceAwsEbsSnapshotRead(d *schema.ResourceData, meta interface{}) erro return snapshotDescriptionAttributes(d, snapshot) } -type snapshotSort []*ec2.Snapshot - -func (a snapshotSort) Len() int { return len(a) } -func (a snapshotSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a snapshotSort) Less(i, j int) bool { - itime := *a[i].StartTime - jtime := *a[j].StartTime - return itime.Unix() < jtime.Unix() -} - func mostRecentSnapshot(snapshots []*ec2.Snapshot) *ec2.Snapshot { - sortedSnapshots := snapshots - sort.Sort(snapshotSort(sortedSnapshots)) - return sortedSnapshots[len(sortedSnapshots)-1] + return sortSnapshots(snapshots)[0] } func snapshotDescriptionAttributes(d *schema.ResourceData, snapshot *ec2.Snapshot) error { diff --git a/builtin/providers/aws/data_source_aws_ebs_snapshot_ids.go b/builtin/providers/aws/data_source_aws_ebs_snapshot_ids.go index 57dc20e9c..bd4f2ad8b 100644 --- a/builtin/providers/aws/data_source_aws_ebs_snapshot_ids.go +++ b/builtin/providers/aws/data_source_aws_ebs_snapshot_ids.go @@ -28,10 +28,9 @@ func dataSourceAwsEbsSnapshotIds() *schema.Resource { }, "tags": dataSourceTagsSchema(), "ids": &schema.Schema{ - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, }, } @@ -67,7 +66,7 @@ func dataSourceAwsEbsSnapshotIdsRead(d *schema.ResourceData, meta interface{}) e snapshotIds := make([]string, 0) - for _, snapshot := range resp.Snapshots { + for _, snapshot := range sortSnapshots(resp.Snapshots) { snapshotIds = append(snapshotIds, *snapshot.SnapshotId) } diff --git a/builtin/providers/aws/data_source_aws_ebs_snapshot_ids_test.go b/builtin/providers/aws/data_source_aws_ebs_snapshot_ids_test.go index 869152ac4..0c5f3ec4d 100644 --- a/builtin/providers/aws/data_source_aws_ebs_snapshot_ids_test.go +++ b/builtin/providers/aws/data_source_aws_ebs_snapshot_ids_test.go @@ -1,9 +1,11 @@ package aws import ( + "fmt" "testing" "github.com/hashicorp/terraform/helper/resource" + "github.com/satori/uuid" ) func TestAccDataSourceAwsEbsSnapshotIds_basic(t *testing.T) { @@ -21,6 +23,37 @@ func TestAccDataSourceAwsEbsSnapshotIds_basic(t *testing.T) { }) } +func TestAccDataSourceAwsEbsSnapshotIds_sorted(t *testing.T) { + uuid := uuid.NewV4().String() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsEbsSnapshotIdsConfig_sorted1(uuid), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("aws_ebs_snapshot.a", "id"), + resource.TestCheckResourceAttrSet("aws_ebs_snapshot.b", "id"), + ), + }, + { + Config: testAccDataSourceAwsEbsSnapshotIdsConfig_sorted2(uuid), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsEbsSnapshotDataSourceID("data.aws_ebs_snapshot_ids.test"), + resource.TestCheckResourceAttr("data.aws_ebs_snapshot_ids.test", "ids.#", "2"), + resource.TestCheckResourceAttrPair( + "data.aws_ebs_snapshot_ids.test", "ids.0", + "aws_ebs_snapshot.b", "id"), + resource.TestCheckResourceAttrPair( + "data.aws_ebs_snapshot_ids.test", "ids.1", + "aws_ebs_snapshot.a", "id"), + ), + }, + }, + }) +} + func TestAccDataSourceAwsEbsSnapshotIds_empty(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -40,7 +73,7 @@ func TestAccDataSourceAwsEbsSnapshotIds_empty(t *testing.T) { const testAccDataSourceAwsEbsSnapshotIdsConfig_basic = ` resource "aws_ebs_volume" "test" { availability_zone = "us-west-2a" - size = 40 + size = 1 } resource "aws_ebs_snapshot" "test" { @@ -52,6 +85,45 @@ data "aws_ebs_snapshot_ids" "test" { } ` +func testAccDataSourceAwsEbsSnapshotIdsConfig_sorted1(uuid string) string { + return fmt.Sprintf(` +resource "aws_ebs_volume" "test" { + availability_zone = "us-west-2a" + size = 1 + + count = 2 +} + +resource "aws_ebs_snapshot" "a" { + volume_id = "${aws_ebs_volume.test.*.id[0]}" + description = "tf-test-%s" +} + +resource "aws_ebs_snapshot" "b" { + volume_id = "${aws_ebs_volume.test.*.id[1]}" + description = "tf-test-%s" + + // We want to ensure that 'aws_ebs_snapshot.a.creation_date' is less than + // 'aws_ebs_snapshot.b.creation_date'/ so that we can ensure that the + // snapshots are being sorted correctly. + depends_on = ["aws_ebs_snapshot.a"] +} +`, uuid, uuid) +} + +func testAccDataSourceAwsEbsSnapshotIdsConfig_sorted2(uuid string) string { + return testAccDataSourceAwsEbsSnapshotIdsConfig_sorted1(uuid) + fmt.Sprintf(` +data "aws_ebs_snapshot_ids" "test" { + owners = ["self"] + + filter { + name = "description" + values = ["tf-test-%s"] + } +} +`, uuid) +} + const testAccDataSourceAwsEbsSnapshotIdsConfig_empty = ` data "aws_ebs_snapshot_ids" "empty" { owners = ["000000000000"] diff --git a/builtin/providers/aws/data_source_aws_subnet_ids.go b/builtin/providers/aws/data_source_aws_subnet_ids.go index efe6c75a4..c1a495aa1 100644 --- a/builtin/providers/aws/data_source_aws_subnet_ids.go +++ b/builtin/providers/aws/data_source_aws_subnet_ids.go @@ -12,10 +12,14 @@ func dataSourceAwsSubnetIDs() *schema.Resource { return &schema.Resource{ Read: dataSourceAwsSubnetIDsRead, Schema: map[string]*schema.Schema{ + + "tags": tagsSchemaComputed(), + "vpc_id": &schema.Schema{ Type: schema.TypeString, Required: true, }, + "ids": &schema.Schema{ Type: schema.TypeSet, Computed: true, @@ -37,6 +41,10 @@ func dataSourceAwsSubnetIDsRead(d *schema.ResourceData, meta interface{}) error }, ) + req.Filters = append(req.Filters, buildEC2TagFilterList( + tagsFromMap(d.Get("tags").(map[string]interface{})), + )...) + log.Printf("[DEBUG] DescribeSubnets %s\n", req) resp, err := conn.DescribeSubnets(req) if err != nil { diff --git a/builtin/providers/aws/data_source_aws_subnet_ids_test.go b/builtin/providers/aws/data_source_aws_subnet_ids_test.go index 36f6c4b91..5d752a25e 100644 --- a/builtin/providers/aws/data_source_aws_subnet_ids_test.go +++ b/builtin/providers/aws/data_source_aws_subnet_ids_test.go @@ -21,7 +21,8 @@ func TestAccDataSourceAwsSubnetIDs(t *testing.T) { { Config: testAccDataSourceAwsSubnetIDsConfigWithDataSource(rInt), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_subnet_ids.selected", "ids.#", "1"), + resource.TestCheckResourceAttr("data.aws_subnet_ids.selected", "ids.#", "3"), + resource.TestCheckResourceAttr("data.aws_subnet_ids.private", "ids.#", "2"), ), }, }, @@ -39,20 +40,50 @@ func testAccDataSourceAwsSubnetIDsConfigWithDataSource(rInt int) string { } } - resource "aws_subnet" "test" { + resource "aws_subnet" "test_public_a" { vpc_id = "${aws_vpc.test.id}" cidr_block = "172.%d.123.0/24" availability_zone = "us-west-2a" tags { - Name = "terraform-testacc-subnet-ids-data-source" + Name = "terraform-testacc-subnet-ids-data-source-public-a" + Tier = "Public" + } + } + + resource "aws_subnet" "test_private_a" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.125.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-a" + Tier = "Private" + } + } + + resource "aws_subnet" "test_private_b" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.126.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-b" + Tier = "Private" } } data "aws_subnet_ids" "selected" { vpc_id = "${aws_vpc.test.id}" } - `, rInt, rInt) + + data "aws_subnet_ids" "private" { + vpc_id = "${aws_vpc.test.id}" + tags { + Tier = "Private" + } + } + `, rInt, rInt, rInt, rInt) } func testAccDataSourceAwsSubnetIDsConfig(rInt int) string { @@ -65,14 +96,37 @@ func testAccDataSourceAwsSubnetIDsConfig(rInt int) string { } } - resource "aws_subnet" "test" { + resource "aws_subnet" "test_public_a" { vpc_id = "${aws_vpc.test.id}" cidr_block = "172.%d.123.0/24" availability_zone = "us-west-2a" tags { - Name = "terraform-testacc-subnet-ids-data-source" + Name = "terraform-testacc-subnet-ids-data-source-public-a" + Tier = "Public" } } - `, rInt, rInt) + + resource "aws_subnet" "test_private_a" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.125.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-a" + Tier = "Private" + } + } + + resource "aws_subnet" "test_private_b" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "172.%d.126.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "terraform-testacc-subnet-ids-data-source-private-b" + Tier = "Private" + } + } + `, rInt, rInt, rInt, rInt) } diff --git a/builtin/providers/aws/import_aws_glacier_vault_test.go b/builtin/providers/aws/import_aws_glacier_vault_test.go index e5fd5aa5b..f7c20666e 100644 --- a/builtin/providers/aws/import_aws_glacier_vault_test.go +++ b/builtin/providers/aws/import_aws_glacier_vault_test.go @@ -3,11 +3,13 @@ package aws import ( "testing" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" ) func TestAccAWSGlacierVault_importBasic(t *testing.T) { resourceName := "aws_glacier_vault.full" + rInt := acctest.RandInt() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -15,7 +17,7 @@ func TestAccAWSGlacierVault_importBasic(t *testing.T) { CheckDestroy: testAccCheckGlacierVaultDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccGlacierVault_full, + Config: testAccGlacierVault_full(rInt), }, resource.TestStep{ diff --git a/builtin/providers/aws/resource_aws_alb.go b/builtin/providers/aws/resource_aws_alb.go index ed756e939..fe94dd0fa 100644 --- a/builtin/providers/aws/resource_aws_alb.go +++ b/builtin/providers/aws/resource_aws_alb.go @@ -48,7 +48,7 @@ func resourceAwsAlb() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, - ValidateFunc: validateElbName, + ValidateFunc: validateElbNamePrefix, }, "internal": { diff --git a/builtin/providers/aws/resource_aws_alb_test.go b/builtin/providers/aws/resource_aws_alb_test.go index fbebb390d..807d1f4e5 100644 --- a/builtin/providers/aws/resource_aws_alb_test.go +++ b/builtin/providers/aws/resource_aws_alb_test.go @@ -113,7 +113,7 @@ func TestAccAWSALB_namePrefix(t *testing.T) { testAccCheckAWSALBExists("aws_alb.alb_test", &conf), resource.TestCheckResourceAttrSet("aws_alb.alb_test", "name"), resource.TestMatchResourceAttr("aws_alb.alb_test", "name", - regexp.MustCompile("^tf-lb")), + regexp.MustCompile("^tf-lb-")), ), }, }, @@ -851,7 +851,7 @@ resource "aws_security_group" "alb_test" { func testAccAWSALBConfig_namePrefix() string { return fmt.Sprintf(` resource "aws_alb" "alb_test" { - name_prefix = "tf-lb" + name_prefix = "tf-lb-" internal = true security_groups = ["${aws_security_group.alb_test.id}"] subnets = ["${aws_subnet.alb_test.*.id}"] diff --git a/builtin/providers/aws/resource_aws_cloudfront_distribution.go b/builtin/providers/aws/resource_aws_cloudfront_distribution.go index aae05c568..6450e7d03 100644 --- a/builtin/providers/aws/resource_aws_cloudfront_distribution.go +++ b/builtin/providers/aws/resource_aws_cloudfront_distribution.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/errwrap" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" ) func resourceAwsCloudFrontDistribution() *schema.Resource { @@ -356,6 +357,18 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Type: schema.TypeInt, Required: true, }, + "origin_keepalive_timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 5, + ValidateFunc: validation.IntBetween(1, 60), + }, + "origin_read_timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 30, + ValidateFunc: validation.IntBetween(4, 60), + }, "origin_protocol_policy": { Type: schema.TypeString, Required: true, diff --git a/builtin/providers/aws/resource_aws_cloudfront_distribution_test.go b/builtin/providers/aws/resource_aws_cloudfront_distribution_test.go index 05f4a48e4..6fab7cbb5 100644 --- a/builtin/providers/aws/resource_aws_cloudfront_distribution_test.go +++ b/builtin/providers/aws/resource_aws_cloudfront_distribution_test.go @@ -27,7 +27,7 @@ func TestAccAWSCloudFrontDistribution_S3Origin(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testConfig, Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExistence( @@ -95,7 +95,7 @@ func TestAccAWSCloudFrontDistribution_customOrigin(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccAWSCloudFrontDistributionCustomConfig, Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExistence( @@ -118,7 +118,7 @@ func TestAccAWSCloudFrontDistribution_multiOrigin(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccAWSCloudFrontDistributionMultiOriginConfig, Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExistence( @@ -141,7 +141,7 @@ func TestAccAWSCloudFrontDistribution_noOptionalItemsConfig(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccAWSCloudFrontDistributionNoOptionalItemsConfig, Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExistence( @@ -165,7 +165,7 @@ func TestAccAWSCloudFrontDistribution_HTTP11Config(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccAWSCloudFrontDistributionHTTP11Config, Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExistence( @@ -183,7 +183,7 @@ func TestAccAWSCloudFrontDistribution_IsIPV6EnabledConfig(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccAWSCloudFrontDistributionIsIPV6EnabledConfig, Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExistence( @@ -203,7 +203,7 @@ func TestAccAWSCloudFrontDistribution_noCustomErrorResponseConfig(t *testing.T) Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccAWSCloudFrontDistributionNoCustomErroResponseInfo, Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExistence( @@ -477,6 +477,8 @@ resource "aws_cloudfront_distribution" "custom_distribution" { https_port = 443 origin_protocol_policy = "http-only" origin_ssl_protocols = [ "SSLv3", "TLSv1" ] + origin_read_timeout = 30 + origin_keepalive_timeout = 5 } } enabled = true @@ -542,6 +544,7 @@ resource "aws_cloudfront_distribution" "multi_origin_distribution" { https_port = 443 origin_protocol_policy = "http-only" origin_ssl_protocols = [ "SSLv3", "TLSv1" ] + origin_keepalive_timeout = 45 } } enabled = true diff --git a/builtin/providers/aws/resource_aws_cloudtrail_test.go b/builtin/providers/aws/resource_aws_cloudtrail_test.go index bf99e8614..08655ea67 100644 --- a/builtin/providers/aws/resource_aws_cloudtrail_test.go +++ b/builtin/providers/aws/resource_aws_cloudtrail_test.go @@ -5,15 +5,41 @@ import ( "log" "testing" + "regexp" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudtrail" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - "regexp" ) -func TestAccAWSCloudTrail_basic(t *testing.T) { +func TestAccAWSCloudTrail(t *testing.T) { + testCases := map[string]map[string]func(t *testing.T){ + "Trail": { + "basic": testAccAWSCloudTrail_basic, + "enableLogging": testAccAWSCloudTrail_enable_logging, + "isMultiRegion": testAccAWSCloudTrail_is_multi_region, + "logValidation": testAccAWSCloudTrail_logValidation, + "kmsKey": testAccAWSCloudTrail_kmsKey, + "tags": testAccAWSCloudTrail_tags, + }, + } + + for group, m := range testCases { + m := m + t.Run(group, func(t *testing.T) { + for name, tc := range m { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } + }) + } +} + +func testAccAWSCloudTrail_basic(t *testing.T) { var trail cloudtrail.Trail cloudTrailRandInt := acctest.RandInt() @@ -45,7 +71,7 @@ func TestAccAWSCloudTrail_basic(t *testing.T) { }) } -func TestAccAWSCloudTrail_enable_logging(t *testing.T) { +func testAccAWSCloudTrail_enable_logging(t *testing.T) { var trail cloudtrail.Trail cloudTrailRandInt := acctest.RandInt() @@ -87,7 +113,7 @@ func TestAccAWSCloudTrail_enable_logging(t *testing.T) { }) } -func TestAccAWSCloudTrail_is_multi_region(t *testing.T) { +func testAccAWSCloudTrail_is_multi_region(t *testing.T) { var trail cloudtrail.Trail cloudTrailRandInt := acctest.RandInt() @@ -127,7 +153,7 @@ func TestAccAWSCloudTrail_is_multi_region(t *testing.T) { }) } -func TestAccAWSCloudTrail_logValidation(t *testing.T) { +func testAccAWSCloudTrail_logValidation(t *testing.T) { var trail cloudtrail.Trail cloudTrailRandInt := acctest.RandInt() @@ -160,7 +186,7 @@ func TestAccAWSCloudTrail_logValidation(t *testing.T) { }) } -func TestAccAWSCloudTrail_kmsKey(t *testing.T) { +func testAccAWSCloudTrail_kmsKey(t *testing.T) { var trail cloudtrail.Trail cloudTrailRandInt := acctest.RandInt() keyRegex := regexp.MustCompile("^arn:aws:([a-zA-Z0-9\\-])+:([a-z]{2}-[a-z]+-\\d{1})?:(\\d{12})?:(.*)$") @@ -184,7 +210,7 @@ func TestAccAWSCloudTrail_kmsKey(t *testing.T) { }) } -func TestAccAWSCloudTrail_tags(t *testing.T) { +func testAccAWSCloudTrail_tags(t *testing.T) { var trail cloudtrail.Trail var trailTags []*cloudtrail.Tag var trailTagsModified []*cloudtrail.Tag diff --git a/builtin/providers/aws/resource_aws_ebs_volume.go b/builtin/providers/aws/resource_aws_ebs_volume.go index 49d5281a1..1beda135e 100644 --- a/builtin/providers/aws/resource_aws_ebs_volume.go +++ b/builtin/providers/aws/resource_aws_ebs_volume.go @@ -179,7 +179,7 @@ func resourceAWSEbsVolumeUpdate(d *schema.ResourceData, meta interface{}) error stateConf := &resource.StateChangeConf{ Pending: []string{"creating", "modifying"}, - Target: []string{"available"}, + Target: []string{"available", "in-use"}, Refresh: volumeStateRefreshFunc(conn, *result.VolumeModification.VolumeId), Timeout: 5 * time.Minute, Delay: 10 * time.Second, diff --git a/builtin/providers/aws/resource_aws_ebs_volume_test.go b/builtin/providers/aws/resource_aws_ebs_volume_test.go index bb98265a2..1c62247ed 100644 --- a/builtin/providers/aws/resource_aws_ebs_volume_test.go +++ b/builtin/providers/aws/resource_aws_ebs_volume_test.go @@ -30,6 +30,31 @@ func TestAccAWSEBSVolume_basic(t *testing.T) { }) } +func TestAccAWSEBSVolume_updateAttachedEbsVolume(t *testing.T) { + var v ec2.Volume + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_ebs_volume.test", + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccAwsEbsAttachedVolumeConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckVolumeExists("aws_ebs_volume.test", &v), + resource.TestCheckResourceAttr("aws_ebs_volume.test", "size", "10"), + ), + }, + { + Config: testAccAwsEbsAttachedVolumeConfigUpdateSize, + Check: resource.ComposeTestCheckFunc( + testAccCheckVolumeExists("aws_ebs_volume.test", &v), + resource.TestCheckResourceAttr("aws_ebs_volume.test", "size", "20"), + ), + }, + }, + }) +} + func TestAccAWSEBSVolume_updateSize(t *testing.T) { var v ec2.Volume resource.Test(t, resource.TestCase{ @@ -200,6 +225,124 @@ resource "aws_ebs_volume" "test" { } ` +const testAccAwsEbsAttachedVolumeConfig = ` +data "aws_ami" "debian_jessie_latest" { + most_recent = true + + filter { + name = "name" + values = ["debian-jessie-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } + + filter { + name = "root-device-type" + values = ["ebs"] + } + + owners = ["379101102735"] # Debian +} + +resource "aws_instance" "test" { + ami = "${data.aws_ami.debian_jessie_latest.id}" + associate_public_ip_address = true + count = 1 + instance_type = "t2.medium" + + root_block_device { + volume_size = "10" + volume_type = "standard" + delete_on_termination = true + } + + tags { + Name = "test-terraform" + } +} + +resource "aws_ebs_volume" "test" { + depends_on = ["aws_instance.test"] + availability_zone = "${aws_instance.test.availability_zone}" + type = "gp2" + size = "10" +} + +resource "aws_volume_attachment" "test" { + depends_on = ["aws_ebs_volume.test"] + device_name = "/dev/xvdg" + volume_id = "${aws_ebs_volume.test.id}" + instance_id = "${aws_instance.test.id}" +} +` + +const testAccAwsEbsAttachedVolumeConfigUpdateSize = ` +data "aws_ami" "debian_jessie_latest" { + most_recent = true + + filter { + name = "name" + values = ["debian-jessie-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } + + filter { + name = "root-device-type" + values = ["ebs"] + } + + owners = ["379101102735"] # Debian +} + +resource "aws_instance" "test" { + ami = "${data.aws_ami.debian_jessie_latest.id}" + associate_public_ip_address = true + count = 1 + instance_type = "t2.medium" + + root_block_device { + volume_size = "10" + volume_type = "standard" + delete_on_termination = true + } + + tags { + Name = "test-terraform" + } +} + +resource "aws_ebs_volume" "test" { + depends_on = ["aws_instance.test"] + availability_zone = "${aws_instance.test.availability_zone}" + type = "gp2" + size = "20" +} + +resource "aws_volume_attachment" "test" { + depends_on = ["aws_ebs_volume.test"] + device_name = "/dev/xvdg" + volume_id = "${aws_ebs_volume.test.id}" + instance_id = "${aws_instance.test.id}" +} +` + const testAccAwsEbsVolumeConfigUpdateSize = ` resource "aws_ebs_volume" "test" { availability_zone = "us-west-2a" diff --git a/builtin/providers/aws/resource_aws_ecs_service_test.go b/builtin/providers/aws/resource_aws_ecs_service_test.go index f622d64b7..c3a603547 100644 --- a/builtin/providers/aws/resource_aws_ecs_service_test.go +++ b/builtin/providers/aws/resource_aws_ecs_service_test.go @@ -85,20 +85,21 @@ func TestParseTaskDefinition(t *testing.T) { } func TestAccAWSEcsServiceWithARN(t *testing.T) { + rInt := acctest.RandInt() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSEcsService, + Config: testAccAWSEcsService(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), ), }, { - Config: testAccAWSEcsServiceModified, + Config: testAccAWSEcsServiceModified(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), ), @@ -181,13 +182,14 @@ func TestAccAWSEcsService_withIamRole(t *testing.T) { } func TestAccAWSEcsService_withDeploymentValues(t *testing.T) { + rInt := acctest.RandInt() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSEcsServiceWithDeploymentValues, + Config: testAccAWSEcsServiceWithDeploymentValues(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr( @@ -262,20 +264,21 @@ func TestAccAWSEcsService_withAlb(t *testing.T) { } func TestAccAWSEcsServiceWithPlacementStrategy(t *testing.T) { + rInt := acctest.RandInt() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSEcsService, + Config: testAccAWSEcsService(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_strategy.#", "0"), ), }, { - Config: testAccAWSEcsServiceWithPlacementStrategy, + Config: testAccAWSEcsServiceWithPlacementStrategy(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_strategy.#", "1"), @@ -286,13 +289,14 @@ func TestAccAWSEcsServiceWithPlacementStrategy(t *testing.T) { } func TestAccAWSEcsServiceWithPlacementConstraints(t *testing.T) { + rInt := acctest.RandInt() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSEcsServiceWithPlacementConstraint, + Config: testAccAWSEcsServiceWithPlacementConstraint(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_constraints.#", "1"), @@ -303,13 +307,14 @@ func TestAccAWSEcsServiceWithPlacementConstraints(t *testing.T) { } func TestAccAWSEcsServiceWithPlacementConstraints_emptyExpression(t *testing.T) { + rInt := acctest.RandInt() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSEcsServiceWithPlacementConstraintEmptyExpression, + Config: testAccAWSEcsServiceWithPlacementConstraintEmptyExpression(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_constraints.#", "1"), @@ -366,9 +371,10 @@ func testAccCheckAWSEcsServiceExists(name string) resource.TestCheckFunc { } } -var testAccAWSEcsService = ` +func testAccAWSEcsService(rInt int) string { + return fmt.Sprintf(` resource "aws_ecs_cluster" "default" { - name = "terraformecstest1" + name = "terraformecstest%d" } resource "aws_ecs_task_definition" "mongo" { @@ -387,16 +393,18 @@ DEFINITION } resource "aws_ecs_service" "mongo" { - name = "mongodb" + name = "mongodb-%d" cluster = "${aws_ecs_cluster.default.id}" task_definition = "${aws_ecs_task_definition.mongo.arn}" desired_count = 1 } -` +`, rInt, rInt) +} -var testAccAWSEcsServiceModified = ` +func testAccAWSEcsServiceModified(rInt int) string { + return fmt.Sprintf(` resource "aws_ecs_cluster" "default" { - name = "terraformecstest1" + name = "terraformecstest%d" } resource "aws_ecs_task_definition" "mongo" { @@ -415,16 +423,18 @@ DEFINITION } resource "aws_ecs_service" "mongo" { - name = "mongodb" + name = "mongodb-%d" cluster = "${aws_ecs_cluster.default.id}" task_definition = "${aws_ecs_task_definition.mongo.arn}" desired_count = 2 } -` +`, rInt, rInt) +} -var testAccAWSEcsServiceWithPlacementStrategy = ` +func testAccAWSEcsServiceWithPlacementStrategy(rInt int) string { + return fmt.Sprintf(` resource "aws_ecs_cluster" "default" { - name = "terraformecstest1" + name = "terraformecstest%d" } resource "aws_ecs_task_definition" "mongo" { @@ -443,7 +453,7 @@ DEFINITION } resource "aws_ecs_service" "mongo" { - name = "mongodb" + name = "mongodb-%d" cluster = "${aws_ecs_cluster.default.id}" task_definition = "${aws_ecs_task_definition.mongo.arn}" desired_count = 1 @@ -452,43 +462,47 @@ resource "aws_ecs_service" "mongo" { field = "memory" } } -` +`, rInt, rInt) +} -var testAccAWSEcsServiceWithPlacementConstraint = ` +func testAccAWSEcsServiceWithPlacementConstraint(rInt int) string { + return fmt.Sprintf(` + resource "aws_ecs_cluster" "default" { + name = "terraformecstest%d" + } + + resource "aws_ecs_task_definition" "mongo" { + family = "mongodb" + container_definitions = < 0 { + runOpts.TagSpecifications = tagsSpec + } + // Create the instance log.Printf("[DEBUG] Run configuration: %s", runOpts) @@ -528,23 +592,62 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { d.Set("private_ip", instance.PrivateIpAddress) d.Set("iam_instance_profile", iamInstanceProfileArnToName(instance.IamInstanceProfile)) + // Set configured Network Interface Device Index Slice + // We only want to read, and populate state for the configured network_interface attachments. Otherwise, other + // resources have the potential to attach network interfaces to the instance, and cause a perpetual create/destroy + // diff. We should only read on changes configured for this specific resource because of this. + var configuredDeviceIndexes []int + if v, ok := d.GetOk("network_interface"); ok { + vL := v.(*schema.Set).List() + for _, vi := range vL { + mVi := vi.(map[string]interface{}) + configuredDeviceIndexes = append(configuredDeviceIndexes, mVi["device_index"].(int)) + } + } + var ipv6Addresses []string if len(instance.NetworkInterfaces) > 0 { - for _, ni := range instance.NetworkInterfaces { - if *ni.Attachment.DeviceIndex == 0 { - d.Set("subnet_id", ni.SubnetId) - d.Set("network_interface_id", ni.NetworkInterfaceId) - d.Set("associate_public_ip_address", ni.Association != nil) - d.Set("ipv6_address_count", len(ni.Ipv6Addresses)) - - for _, address := range ni.Ipv6Addresses { - ipv6Addresses = append(ipv6Addresses, *address.Ipv6Address) + var primaryNetworkInterface ec2.InstanceNetworkInterface + var networkInterfaces []map[string]interface{} + for _, iNi := range instance.NetworkInterfaces { + ni := make(map[string]interface{}) + if *iNi.Attachment.DeviceIndex == 0 { + primaryNetworkInterface = *iNi + } + // If the attached network device is inside our configuration, refresh state with values found. + // Otherwise, assume the network device was attached via an outside resource. + for _, index := range configuredDeviceIndexes { + if index == int(*iNi.Attachment.DeviceIndex) { + ni["device_index"] = *iNi.Attachment.DeviceIndex + ni["network_interface_id"] = *iNi.NetworkInterfaceId + ni["delete_on_termination"] = *iNi.Attachment.DeleteOnTermination } } + // Don't add empty network interfaces to schema + if len(ni) == 0 { + continue + } + networkInterfaces = append(networkInterfaces, ni) } + if err := d.Set("network_interface", networkInterfaces); err != nil { + return fmt.Errorf("Error setting network_interfaces: %v", err) + } + + // Set primary network interface details + d.Set("subnet_id", primaryNetworkInterface.SubnetId) + d.Set("network_interface_id", primaryNetworkInterface.NetworkInterfaceId) // TODO: Deprecate me v0.10.0 + d.Set("primary_network_interface_id", primaryNetworkInterface.NetworkInterfaceId) + d.Set("associate_public_ip_address", primaryNetworkInterface.Association != nil) + d.Set("ipv6_address_count", len(primaryNetworkInterface.Ipv6Addresses)) + + for _, address := range primaryNetworkInterface.Ipv6Addresses { + ipv6Addresses = append(ipv6Addresses, *address.Ipv6Address) + } + } else { d.Set("subnet_id", instance.SubnetId) - d.Set("network_interface_id", "") + d.Set("network_interface_id", "") // TODO: Deprecate me v0.10.0 + d.Set("primary_network_interface_id", "") } if err := d.Set("ipv6_addresses", ipv6Addresses); err != nil { @@ -563,6 +666,10 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { d.Set("tags", tagsToMap(instance.Tags)) + if err := readVolumeTags(conn, d); err != nil { + return err + } + if err := readSecurityGroups(d, instance); err != nil { return err } @@ -605,16 +712,27 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn d.Partial(true) - if err := setTags(conn, d); err != nil { - return err - } else { - d.SetPartial("tags") + + if d.HasChange("tags") && !d.IsNewResource() { + if err := setTags(conn, d); err != nil { + return err + } else { + d.SetPartial("tags") + } + } + + if d.HasChange("volume_tags") && !d.IsNewResource() { + if err := setVolumeTags(conn, d); err != nil { + return err + } else { + d.SetPartial("volume_tags") + } } if d.HasChange("iam_instance_profile") && !d.IsNewResource() { request := &ec2.DescribeIamInstanceProfileAssociationsInput{ Filters: []*ec2.Filter{ - &ec2.Filter{ + { Name: aws.String("instance-id"), Values: []*string{aws.String(d.Id())}, }, @@ -671,24 +789,28 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { } } - if d.HasChange("source_dest_check") || d.IsNewResource() { - // SourceDestCheck can only be set on VPC instances // AWS will return an error of InvalidParameterCombination if we attempt - // to modify the source_dest_check of an instance in EC2 Classic - log.Printf("[INFO] Modifying `source_dest_check` on Instance %s", d.Id()) - _, err := conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{ - InstanceId: aws.String(d.Id()), - SourceDestCheck: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("source_dest_check").(bool)), - }, - }) - if err != nil { - if ec2err, ok := err.(awserr.Error); ok { - // Toloerate InvalidParameterCombination error in Classic, otherwise - // return the error - if "InvalidParameterCombination" != ec2err.Code() { - return err + // SourceDestCheck can only be modified on an instance without manually specified network interfaces. + // SourceDestCheck, in that case, is configured at the network interface level + if _, ok := d.GetOk("network_interface"); !ok { + if d.HasChange("source_dest_check") || d.IsNewResource() { + // SourceDestCheck can only be set on VPC instances // AWS will return an error of InvalidParameterCombination if we attempt + // to modify the source_dest_check of an instance in EC2 Classic + log.Printf("[INFO] Modifying `source_dest_check` on Instance %s", d.Id()) + _, err := conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{ + InstanceId: aws.String(d.Id()), + SourceDestCheck: &ec2.AttributeBooleanValue{ + Value: aws.Bool(d.Get("source_dest_check").(bool)), + }, + }) + if err != nil { + if ec2err, ok := err.(awserr.Error); ok { + // Tolerate InvalidParameterCombination error in Classic, otherwise + // return the error + if "InvalidParameterCombination" != ec2err.Code() { + return err + } + log.Printf("[WARN] Attempted to modify SourceDestCheck on non VPC instance: %s", ec2err.Message()) } - log.Printf("[WARN] Attempted to modify SourceDestCheck on non VPC instance: %s", ec2err.Message()) } } } @@ -1008,6 +1130,55 @@ func fetchRootDeviceName(ami string, conn *ec2.EC2) (*string, error) { return rootDeviceName, nil } +func buildNetworkInterfaceOpts(d *schema.ResourceData, groups []*string, nInterfaces interface{}) []*ec2.InstanceNetworkInterfaceSpecification { + networkInterfaces := []*ec2.InstanceNetworkInterfaceSpecification{} + // Get necessary items + associatePublicIPAddress := d.Get("associate_public_ip_address").(bool) + subnet, hasSubnet := d.GetOk("subnet_id") + + if hasSubnet && associatePublicIPAddress { + // If we have a non-default VPC / Subnet specified, we can flag + // AssociatePublicIpAddress to get a Public IP assigned. By default these are not provided. + // You cannot specify both SubnetId and the NetworkInterface.0.* parameters though, otherwise + // you get: Network interfaces and an instance-level subnet ID may not be specified on the same request + // You also need to attach Security Groups to the NetworkInterface instead of the instance, + // to avoid: Network interfaces and an instance-level security groups may not be specified on + // the same request + ni := &ec2.InstanceNetworkInterfaceSpecification{ + AssociatePublicIpAddress: aws.Bool(associatePublicIPAddress), + DeviceIndex: aws.Int64(int64(0)), + SubnetId: aws.String(subnet.(string)), + Groups: groups, + } + + if v, ok := d.GetOk("private_ip"); ok { + ni.PrivateIpAddress = aws.String(v.(string)) + } + + if v := d.Get("vpc_security_group_ids").(*schema.Set); v.Len() > 0 { + for _, v := range v.List() { + ni.Groups = append(ni.Groups, aws.String(v.(string))) + } + } + + networkInterfaces = append(networkInterfaces, ni) + } else { + // If we have manually specified network interfaces, build and attach those here. + vL := nInterfaces.(*schema.Set).List() + for _, v := range vL { + ini := v.(map[string]interface{}) + ni := &ec2.InstanceNetworkInterfaceSpecification{ + DeviceIndex: aws.Int64(int64(ini["device_index"].(int))), + NetworkInterfaceId: aws.String(ini["network_interface_id"].(string)), + DeleteOnTermination: aws.Bool(ini["delete_on_termination"].(bool)), + } + networkInterfaces = append(networkInterfaces, ni) + } + } + + return networkInterfaces +} + func readBlockDeviceMappingsFromConfig( d *schema.ResourceData, conn *ec2.EC2) ([]*ec2.BlockDeviceMapping, error) { blockDevices := make([]*ec2.BlockDeviceMapping, 0) @@ -1125,6 +1296,39 @@ func readBlockDeviceMappingsFromConfig( return blockDevices, nil } +func readVolumeTags(conn *ec2.EC2, d *schema.ResourceData) error { + volumeIds, err := getAwsInstanceVolumeIds(conn, d) + if err != nil { + return err + } + + tagsResp, err := conn.DescribeTags(&ec2.DescribeTagsInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("resource-id"), + Values: volumeIds, + }, + }, + }) + if err != nil { + return err + } + + var tags []*ec2.Tag + + for _, t := range tagsResp.Tags { + tag := &ec2.Tag{ + Key: t.Key, + Value: t.Value, + } + tags = append(tags, tag) + } + + d.Set("volume_tags", tagsToMap(tags)) + + return nil +} + // Determine whether we're referring to security groups with // IDs or names. We use a heuristic to figure this out. By default, // we use IDs if we're in a VPC. However, if we previously had an @@ -1260,33 +1464,14 @@ func buildAwsInstanceOpts( } } - if hasSubnet && associatePublicIPAddress { - // If we have a non-default VPC / Subnet specified, we can flag - // AssociatePublicIpAddress to get a Public IP assigned. By default these are not provided. - // You cannot specify both SubnetId and the NetworkInterface.0.* parameters though, otherwise - // you get: Network interfaces and an instance-level subnet ID may not be specified on the same request - // You also need to attach Security Groups to the NetworkInterface instead of the instance, - // to avoid: Network interfaces and an instance-level security groups may not be specified on - // the same request - ni := &ec2.InstanceNetworkInterfaceSpecification{ - AssociatePublicIpAddress: aws.Bool(associatePublicIPAddress), - DeviceIndex: aws.Int64(int64(0)), - SubnetId: aws.String(subnetID), - Groups: groups, - } + networkInterfaces, interfacesOk := d.GetOk("network_interface") - if v, ok := d.GetOk("private_ip"); ok { - ni.PrivateIpAddress = aws.String(v.(string)) - } - - if v := d.Get("vpc_security_group_ids").(*schema.Set); v.Len() > 0 { - for _, v := range v.List() { - ni.Groups = append(ni.Groups, aws.String(v.(string))) - } - } - - opts.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{ni} + // If setting subnet and public address, OR manual network interfaces, populate those now. + if hasSubnet && associatePublicIPAddress || interfacesOk { + // Otherwise we're attaching (a) network interface(s) + opts.NetworkInterfaces = buildNetworkInterfaceOpts(d, groups, networkInterfaces) } else { + // If simply specifying a subnetID, privateIP, Security Groups, or VPC Security Groups, build these now if subnetID != "" { opts.SubnetID = aws.String(subnetID) } @@ -1319,7 +1504,6 @@ func buildAwsInstanceOpts( if len(blockDevices) > 0 { opts.BlockDeviceMappings = blockDevices } - return opts, nil } @@ -1372,3 +1556,27 @@ func userDataHashSum(user_data string) string { hash := sha1.Sum(v) return hex.EncodeToString(hash[:]) } + +func getAwsInstanceVolumeIds(conn *ec2.EC2, d *schema.ResourceData) ([]*string, error) { + volumeIds := make([]*string, 0) + + opts := &ec2.DescribeVolumesInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("attachment.instance-id"), + Values: []*string{aws.String(d.Id())}, + }, + }, + } + + resp, err := conn.DescribeVolumes(opts) + if err != nil { + return nil, err + } + + for _, v := range resp.Volumes { + volumeIds = append(volumeIds, v.VolumeId) + } + + return volumeIds, nil +} diff --git a/builtin/providers/aws/resource_aws_instance_migrate.go b/builtin/providers/aws/resource_aws_instance_migrate.go index 28a256b7b..31f28b39f 100644 --- a/builtin/providers/aws/resource_aws_instance_migrate.go +++ b/builtin/providers/aws/resource_aws_instance_migrate.go @@ -15,13 +15,13 @@ func resourceAwsInstanceMigrateState( switch v { case 0: log.Println("[INFO] Found AWS Instance State v0; migrating to v1") - return migrateStateV0toV1(is) + return migrateAwsInstanceStateV0toV1(is) default: return is, fmt.Errorf("Unexpected schema version: %d", v) } } -func migrateStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) { +func migrateAwsInstanceStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) { if is.Empty() || is.Attributes == nil { log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") return is, nil diff --git a/builtin/providers/aws/resource_aws_instance_test.go b/builtin/providers/aws/resource_aws_instance_test.go index 2b835f6d7..01dd6d99c 100644 --- a/builtin/providers/aws/resource_aws_instance_test.go +++ b/builtin/providers/aws/resource_aws_instance_test.go @@ -616,7 +616,6 @@ func TestAccAWSInstance_tags(t *testing.T) { testAccCheckTags(&v.Tags, "#", ""), ), }, - { Config: testAccCheckInstanceConfigTagsUpdate, Check: resource.ComposeTestCheckFunc( @@ -629,6 +628,75 @@ func TestAccAWSInstance_tags(t *testing.T) { }) } +func TestAccAWSInstance_volumeTags(t *testing.T) { + var v ec2.Instance + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckInstanceConfigNoVolumeTags, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &v), + resource.TestCheckNoResourceAttr( + "aws_instance.foo", "volume_tags"), + ), + }, + { + Config: testAccCheckInstanceConfigWithVolumeTags, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &v), + resource.TestCheckResourceAttr( + "aws_instance.foo", "volume_tags.%", "1"), + resource.TestCheckResourceAttr( + "aws_instance.foo", "volume_tags.Name", "acceptance-test-volume-tag"), + ), + }, + { + Config: testAccCheckInstanceConfigWithVolumeTagsUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &v), + resource.TestCheckResourceAttr( + "aws_instance.foo", "volume_tags.%", "2"), + resource.TestCheckResourceAttr( + "aws_instance.foo", "volume_tags.Name", "acceptance-test-volume-tag"), + resource.TestCheckResourceAttr( + "aws_instance.foo", "volume_tags.Environment", "dev"), + ), + }, + { + Config: testAccCheckInstanceConfigNoVolumeTags, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &v), + resource.TestCheckNoResourceAttr( + "aws_instance.foo", "volume_tags"), + ), + }, + }, + }) +} + +func TestAccAWSInstance_volumeTagsComputed(t *testing.T) { + var v ec2.Instance + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckInstanceConfigWithAttachedVolume, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &v), + ), + ExpectNonEmptyPlan: false, + }, + }, + }) +} + func TestAccAWSInstance_instanceProfileChange(t *testing.T) { var v ec2.Instance rName := acctest.RandString(5) @@ -877,6 +945,58 @@ func TestAccAWSInstance_changeInstanceType(t *testing.T) { }) } +func TestAccAWSInstance_primaryNetworkInterface(t *testing.T) { + var instance ec2.Instance + var ini ec2.NetworkInterface + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccInstanceConfigPrimaryNetworkInterface, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &instance), + testAccCheckAWSENIExists("aws_network_interface.bar", &ini), + resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), + ), + }, + }, + }) +} + +func TestAccAWSInstance_addSecondaryInterface(t *testing.T) { + var before ec2.Instance + var after ec2.Instance + var iniPrimary ec2.NetworkInterface + var iniSecondary ec2.NetworkInterface + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccInstanceConfigAddSecondaryNetworkInterfaceBefore, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &before), + testAccCheckAWSENIExists("aws_network_interface.primary", &iniPrimary), + resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), + ), + }, + { + Config: testAccInstanceConfigAddSecondaryNetworkInterfaceAfter, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &after), + testAccCheckAWSENIExists("aws_network_interface.secondary", &iniSecondary), + resource.TestCheckResourceAttr("aws_instance.foo", "network_interface.#", "1"), + ), + }, + }, + }) +} + func testAccCheckInstanceNotRecreated(t *testing.T, before, after *ec2.Instance) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -1281,6 +1401,180 @@ resource "aws_instance" "foo" { } ` +const testAccCheckInstanceConfigWithAttachedVolume = ` +data "aws_ami" "debian_jessie_latest" { + most_recent = true + + filter { + name = "name" + values = ["debian-jessie-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } + + filter { + name = "root-device-type" + values = ["ebs"] + } + + owners = ["379101102735"] # Debian +} + +resource "aws_instance" "foo" { + ami = "${data.aws_ami.debian_jessie_latest.id}" + associate_public_ip_address = true + count = 1 + instance_type = "t2.medium" + + root_block_device { + volume_size = "10" + volume_type = "standard" + delete_on_termination = true + } + + tags { + Name = "test-terraform" + } +} + +resource "aws_ebs_volume" "test" { + depends_on = ["aws_instance.foo"] + availability_zone = "${aws_instance.foo.availability_zone}" + type = "gp2" + size = "10" + + tags { + Name = "test-terraform" + } +} + +resource "aws_volume_attachment" "test" { + depends_on = ["aws_ebs_volume.test"] + device_name = "/dev/xvdg" + volume_id = "${aws_ebs_volume.test.id}" + instance_id = "${aws_instance.foo.id}" +} +` + +const testAccCheckInstanceConfigNoVolumeTags = ` +resource "aws_instance" "foo" { + ami = "ami-55a7ea65" + + instance_type = "m3.medium" + + root_block_device { + volume_type = "gp2" + volume_size = 11 + } + ebs_block_device { + device_name = "/dev/sdb" + volume_size = 9 + } + ebs_block_device { + device_name = "/dev/sdc" + volume_size = 10 + volume_type = "io1" + iops = 100 + } + + ebs_block_device { + device_name = "/dev/sdd" + volume_size = 12 + encrypted = true + } + + ephemeral_block_device { + device_name = "/dev/sde" + virtual_name = "ephemeral0" + } +} +` + +const testAccCheckInstanceConfigWithVolumeTags = ` +resource "aws_instance" "foo" { + ami = "ami-55a7ea65" + + instance_type = "m3.medium" + + root_block_device { + volume_type = "gp2" + volume_size = 11 + } + ebs_block_device { + device_name = "/dev/sdb" + volume_size = 9 + } + ebs_block_device { + device_name = "/dev/sdc" + volume_size = 10 + volume_type = "io1" + iops = 100 + } + + ebs_block_device { + device_name = "/dev/sdd" + volume_size = 12 + encrypted = true + } + + ephemeral_block_device { + device_name = "/dev/sde" + virtual_name = "ephemeral0" + } + + volume_tags { + Name = "acceptance-test-volume-tag" + } +} +` + +const testAccCheckInstanceConfigWithVolumeTagsUpdate = ` +resource "aws_instance" "foo" { + ami = "ami-55a7ea65" + + instance_type = "m3.medium" + + root_block_device { + volume_type = "gp2" + volume_size = 11 + } + ebs_block_device { + device_name = "/dev/sdb" + volume_size = 9 + } + ebs_block_device { + device_name = "/dev/sdc" + volume_size = 10 + volume_type = "io1" + iops = 100 + } + + ebs_block_device { + device_name = "/dev/sdd" + volume_size = 12 + encrypted = true + } + + ephemeral_block_device { + device_name = "/dev/sde" + virtual_name = "ephemeral0" + } + + volume_tags { + Name = "acceptance-test-volume-tag" + Environment = "dev" + } +} +` + const testAccCheckInstanceConfigTagsUpdate = ` resource "aws_instance" "foo" { ami = "ami-4fccb37f" @@ -1536,3 +1830,129 @@ resource "aws_instance" "foo" { subnet_id = "${aws_subnet.foo.id}" } ` + +const testAccInstanceConfigPrimaryNetworkInterface = ` +resource "aws_vpc" "foo" { + cidr_block = "172.16.0.0/16" + tags { + Name = "tf-instance-test" + } +} + +resource "aws_subnet" "foo" { + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "172.16.10.0/24" + availability_zone = "us-west-2a" + tags { + Name = "tf-instance-test" + } +} + +resource "aws_network_interface" "bar" { + subnet_id = "${aws_subnet.foo.id}" + private_ips = ["172.16.10.100"] + tags { + Name = "primary_network_interface" + } +} + +resource "aws_instance" "foo" { + ami = "ami-22b9a343" + instance_type = "t2.micro" + network_interface { + network_interface_id = "${aws_network_interface.bar.id}" + device_index = 0 + } +} +` + +const testAccInstanceConfigAddSecondaryNetworkInterfaceBefore = ` +resource "aws_vpc" "foo" { + cidr_block = "172.16.0.0/16" + tags { + Name = "tf-instance-test" + } +} + +resource "aws_subnet" "foo" { + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "172.16.10.0/24" + availability_zone = "us-west-2a" + tags { + Name = "tf-instance-test" + } +} + +resource "aws_network_interface" "primary" { + subnet_id = "${aws_subnet.foo.id}" + private_ips = ["172.16.10.100"] + tags { + Name = "primary_network_interface" + } +} + +resource "aws_network_interface" "secondary" { + subnet_id = "${aws_subnet.foo.id}" + private_ips = ["172.16.10.101"] + tags { + Name = "secondary_network_interface" + } +} + +resource "aws_instance" "foo" { + ami = "ami-22b9a343" + instance_type = "t2.micro" + network_interface { + network_interface_id = "${aws_network_interface.primary.id}" + device_index = 0 + } +} +` + +const testAccInstanceConfigAddSecondaryNetworkInterfaceAfter = ` +resource "aws_vpc" "foo" { + cidr_block = "172.16.0.0/16" + tags { + Name = "tf-instance-test" + } +} + +resource "aws_subnet" "foo" { + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "172.16.10.0/24" + availability_zone = "us-west-2a" + tags { + Name = "tf-instance-test" + } +} + +resource "aws_network_interface" "primary" { + subnet_id = "${aws_subnet.foo.id}" + private_ips = ["172.16.10.100"] + tags { + Name = "primary_network_interface" + } +} + +// Attach previously created network interface, observe no state diff on instance resource +resource "aws_network_interface" "secondary" { + subnet_id = "${aws_subnet.foo.id}" + private_ips = ["172.16.10.101"] + tags { + Name = "secondary_network_interface" + } + attachment { + instance = "${aws_instance.foo.id}" + device_index = 1 + } +} + +resource "aws_instance" "foo" { + ami = "ami-22b9a343" + instance_type = "t2.micro" + network_interface { + network_interface_id = "${aws_network_interface.primary.id}" + device_index = 0 + } +} +` diff --git a/builtin/providers/aws/resource_aws_sns_topic_subscription_test.go b/builtin/providers/aws/resource_aws_sns_topic_subscription_test.go index 146d2fa92..3f730c9f7 100644 --- a/builtin/providers/aws/resource_aws_sns_topic_subscription_test.go +++ b/builtin/providers/aws/resource_aws_sns_topic_subscription_test.go @@ -31,6 +31,25 @@ func TestAccAWSSNSTopicSubscription_basic(t *testing.T) { }) } +func TestAccAWSSNSTopicSubscription_autoConfirmingEndpoint(t *testing.T) { + ri := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSNSTopicSubscriptionDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSSNSTopicSubscriptionConfig_autoConfirmingEndpoint(ri), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSNSTopicExists("aws_sns_topic.test_topic"), + testAccCheckAWSSNSTopicSubscriptionExists("aws_sns_topic_subscription.test_subscription"), + ), + }, + }, + }) +} + func testAccCheckAWSSNSTopicSubscriptionDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).snsconn @@ -103,3 +122,126 @@ resource "aws_sns_topic_subscription" "test_subscription" { } `, i) } + +func testAccAWSSNSTopicSubscriptionConfig_autoConfirmingEndpoint(i int) string { + return fmt.Sprintf(` +resource "aws_sns_topic" "test_topic" { + name = "tf-acc-test-sns-%d" +} + +resource "aws_api_gateway_rest_api" "test" { + name = "tf-acc-test-sns-%d" + description = "Terraform Acceptance test for SNS subscription" +} + +resource "aws_api_gateway_method" "test" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_rest_api.test.root_resource_id}" + http_method = "POST" + authorization = "NONE" +} + +resource "aws_api_gateway_method_response" "test" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_rest_api.test.root_resource_id}" + http_method = "${aws_api_gateway_method.test.http_method}" + status_code = "200" + + response_parameters { + "method.response.header.Access-Control-Allow-Origin" = true + } +} + +resource "aws_api_gateway_integration" "test" { + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_rest_api.test.root_resource_id}" + http_method = "${aws_api_gateway_method.test.http_method}" + integration_http_method = "POST" + type = "AWS" + uri = "${aws_lambda_function.lambda.invoke_arn}" +} + +resource "aws_api_gateway_integration_response" "test" { + depends_on = ["aws_api_gateway_integration.test"] + rest_api_id = "${aws_api_gateway_rest_api.test.id}" + resource_id = "${aws_api_gateway_rest_api.test.root_resource_id}" + http_method = "${aws_api_gateway_method.test.http_method}" + status_code = "${aws_api_gateway_method_response.test.status_code}" + + response_parameters { + "method.response.header.Access-Control-Allow-Origin" = "'*'" + } +} + +resource "aws_iam_role" "iam_for_lambda" { + name = "tf-acc-test-sns-%d" + + assume_role_policy = < 0 { + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + log.Printf("[DEBUG] Removing volume tags: %#v from %s", remove, d.Id()) + _, err := conn.DeleteTags(&ec2.DeleteTagsInput{ + Resources: volumeIds, + Tags: remove, + }) + if err != nil { + ec2err, ok := err.(awserr.Error) + if ok && strings.Contains(ec2err.Code(), ".NotFound") { + return resource.RetryableError(err) // retry + } + return resource.NonRetryableError(err) + } + return nil + }) + if err != nil { + return err + } + } + if len(create) > 0 { + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + log.Printf("[DEBUG] Creating vol tags: %s for %s", create, d.Id()) + _, err := conn.CreateTags(&ec2.CreateTagsInput{ + Resources: volumeIds, + Tags: create, + }) + if err != nil { + ec2err, ok := err.(awserr.Error) + if ok && strings.Contains(ec2err.Code(), ".NotFound") { + return resource.RetryableError(err) // retry + } + return resource.NonRetryableError(err) + } + return nil + }) + if err != nil { + return err + } + } + } + + return nil +} + // setTags is a helper to set the tags for a resource. It expects the // tags field to be named "tags" func setTags(conn *ec2.EC2, d *schema.ResourceData) error { diff --git a/builtin/providers/aws/test-fixtures/lambda_confirm_sns.zip b/builtin/providers/aws/test-fixtures/lambda_confirm_sns.zip new file mode 100644 index 000000000..c88d2d400 Binary files /dev/null and b/builtin/providers/aws/test-fixtures/lambda_confirm_sns.zip differ diff --git a/builtin/providers/azurerm/resource_arm_virtual_machine.go b/builtin/providers/azurerm/resource_arm_virtual_machine.go index c3f736412..4a01ca374 100644 --- a/builtin/providers/azurerm/resource_arm_virtual_machine.go +++ b/builtin/providers/azurerm/resource_arm_virtual_machine.go @@ -177,8 +177,9 @@ func resourceArmVirtualMachine() *schema.Resource { }, "create_option": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, }, "disk_size_gb": { @@ -232,8 +233,9 @@ func resourceArmVirtualMachine() *schema.Resource { }, "create_option": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, }, "caching": { diff --git a/builtin/providers/dnsimple/import_dnsimple_record_test.go b/builtin/providers/dnsimple/import_dnsimple_record_test.go new file mode 100644 index 000000000..420a6e4c2 --- /dev/null +++ b/builtin/providers/dnsimple/import_dnsimple_record_test.go @@ -0,0 +1,41 @@ +package dnsimple + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccDnsimpleRecord_import(t *testing.T) { + resourceName := "dnsimple_record.foobar" + domain := os.Getenv("DNSIMPLE_DOMAIN") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDNSimpleRecordDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: fmt.Sprintf(testAccCheckDNSimpleRecordConfig_import, domain), + }, + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateIdPrefix: fmt.Sprintf("%s_", domain), + }, + }, + }) +} + +const testAccCheckDNSimpleRecordConfig_import = ` +resource "dnsimple_record" "foobar" { + domain = "%s" + + name = "terraform" + value = "192.168.0.10" + type = "A" + ttl = 3600 +}` diff --git a/builtin/providers/dnsimple/resource_dnsimple_record.go b/builtin/providers/dnsimple/resource_dnsimple_record.go index 3f17977a5..af1c26de9 100644 --- a/builtin/providers/dnsimple/resource_dnsimple_record.go +++ b/builtin/providers/dnsimple/resource_dnsimple_record.go @@ -16,6 +16,9 @@ func resourceDNSimpleRecord() *schema.Resource { Read: resourceDNSimpleRecordRead, Update: resourceDNSimpleRecordUpdate, Delete: resourceDNSimpleRecordDelete, + Importer: &schema.ResourceImporter{ + State: resourceDNSimpleRecordImport, + }, Schema: map[string]*schema.Schema{ "domain": { @@ -184,3 +187,19 @@ func resourceDNSimpleRecordDelete(d *schema.ResourceData, meta interface{}) erro return nil } + +func resourceDNSimpleRecordImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parts := strings.Split(d.Id(), "_") + + if len(parts) != 2 { + return nil, fmt.Errorf("Error Importing dnsimple_record. Please make sure the record ID is in the form DOMAIN_RECORDID (i.e. example.com_1234") + } + + d.SetId(parts[1]) + d.Set("domain", parts[0]) + + if err := resourceDNSimpleRecordRead(d, meta); err != nil { + return nil, err + } + return []*schema.ResourceData{d}, nil +} diff --git a/builtin/providers/fastly/resource_fastly_service_v1.go b/builtin/providers/fastly/resource_fastly_service_v1.go index 89d9218ad..0bec2e728 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1.go +++ b/builtin/providers/fastly/resource_fastly_service_v1.go @@ -2010,7 +2010,7 @@ func resourceServiceV1Read(d *schema.ResourceData, meta interface{}) error { }) if err != nil { - return fmt.Errorf("[ERR] Error looking up GCS for (%s), version (%s): %s", d.Id(), s.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up GCS for (%s), version (%v): %s", d.Id(), s.ActiveVersion.Number, err) } gcsl := flattenGCS(GCSList) diff --git a/builtin/providers/fastly/resource_fastly_service_v1_cache_setting_test.go b/builtin/providers/fastly/resource_fastly_service_v1_cache_setting_test.go index 194a55586..68b9dcee2 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_cache_setting_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_cache_setting_test.go @@ -75,7 +75,7 @@ func testAccCheckFastlyServiceV1CacheSettingsAttributes(service *gofastly.Servic }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Request Setting for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Request Setting for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(rqList) != len(rqs) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_conditionals_test.go b/builtin/providers/fastly/resource_fastly_service_v1_conditionals_test.go index ab64a20d9..0599b7a9c 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_conditionals_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_conditionals_test.go @@ -57,7 +57,7 @@ func testAccCheckFastlyServiceV1ConditionalAttributes(service *gofastly.ServiceD }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Conditions for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Conditions for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(conditionList) != len(conditions) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_gcslogging_test.go b/builtin/providers/fastly/resource_fastly_service_v1_gcslogging_test.go index ed777bf02..a16240f30 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_gcslogging_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_gcslogging_test.go @@ -85,7 +85,7 @@ func testAccCheckFastlyServiceV1Attributes_gcs(service *gofastly.ServiceDetail, }) if err != nil { - return fmt.Errorf("[ERR] Error looking up GCSs for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up GCSs for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(gcsList) != 1 { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_gzip_test.go b/builtin/providers/fastly/resource_fastly_service_v1_gzip_test.go index c1e9db762..91560d4e5 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_gzip_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_gzip_test.go @@ -169,7 +169,7 @@ func testAccCheckFastlyServiceV1GzipsAttributes(service *gofastly.ServiceDetail, }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Gzips for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Gzips for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(gzipsList) != len(gzips) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_headers_test.go b/builtin/providers/fastly/resource_fastly_service_v1_headers_test.go index 1715cee8b..8428c3fcb 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_headers_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_headers_test.go @@ -163,7 +163,7 @@ func testAccCheckFastlyServiceV1HeaderAttributes(service *gofastly.ServiceDetail }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Headers for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Headers for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(headersList) != len(headers) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_healthcheck_test.go b/builtin/providers/fastly/resource_fastly_service_v1_healthcheck_test.go index e78bd0505..c456aa958 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_healthcheck_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_healthcheck_test.go @@ -88,7 +88,7 @@ func testAccCheckFastlyServiceV1HealthCheckAttributes(service *gofastly.ServiceD }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Healthcheck for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Healthcheck for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(healthcheckList) != len(healthchecks) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_papertrail_test.go b/builtin/providers/fastly/resource_fastly_service_v1_papertrail_test.go index f68fbd68f..2e2fcac3d 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_papertrail_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_papertrail_test.go @@ -75,7 +75,7 @@ func testAccCheckFastlyServiceV1PapertrailAttributes(service *gofastly.ServiceDe }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Papertrail for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Papertrail for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(papertrailList) != len(papertrails) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_request_setting_test.go b/builtin/providers/fastly/resource_fastly_service_v1_request_setting_test.go index 3c095c5c7..72d1c3e81 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_request_setting_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_request_setting_test.go @@ -56,7 +56,7 @@ func testAccCheckFastlyServiceV1RequestSettingsAttributes(service *gofastly.Serv }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Request Setting for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Request Setting for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(rqList) != len(rqs) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_response_object_test.go b/builtin/providers/fastly/resource_fastly_service_v1_response_object_test.go index 5399e70a3..e4a2e02b2 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_response_object_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_response_object_test.go @@ -80,7 +80,7 @@ func testAccCheckFastlyServiceV1ResponseObjectAttributes(service *gofastly.Servi }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Response Object for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Response Object for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(responseObjectList) != len(responseObjects) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_s3logging_test.go b/builtin/providers/fastly/resource_fastly_service_v1_s3logging_test.go index e85c88755..651eceac3 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_s3logging_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_s3logging_test.go @@ -171,7 +171,7 @@ func testAccCheckFastlyServiceV1S3LoggingAttributes(service *gofastly.ServiceDet }) if err != nil { - return fmt.Errorf("[ERR] Error looking up S3 Logging for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up S3 Logging for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(s3List) != len(s3s) { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_sumologic_test.go b/builtin/providers/fastly/resource_fastly_service_v1_sumologic_test.go index f3c4b0f69..ca7aabae9 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_sumologic_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_sumologic_test.go @@ -83,7 +83,7 @@ func testAccCheckFastlyServiceV1Attributes_sumologic(service *gofastly.ServiceDe }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Sumologics for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Sumologics for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(sumologicList) != 1 { diff --git a/builtin/providers/fastly/resource_fastly_service_v1_test.go b/builtin/providers/fastly/resource_fastly_service_v1_test.go index 9b6f0defb..e4c853057 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_test.go @@ -305,7 +305,7 @@ func testAccCheckFastlyServiceV1Attributes(service *gofastly.ServiceDetail, name }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Domains for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Domains for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } expected := len(domains) @@ -339,7 +339,7 @@ func testAccCheckFastlyServiceV1Attributes_backends(service *gofastly.ServiceDet }) if err != nil { - return fmt.Errorf("[ERR] Error looking up Backends for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up Backends for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } expected := len(backendList) diff --git a/builtin/providers/fastly/resource_fastly_service_v1_vcl_test.go b/builtin/providers/fastly/resource_fastly_service_v1_vcl_test.go index c95a0f2d0..621e6d1da 100644 --- a/builtin/providers/fastly/resource_fastly_service_v1_vcl_test.go +++ b/builtin/providers/fastly/resource_fastly_service_v1_vcl_test.go @@ -61,7 +61,7 @@ func testAccCheckFastlyServiceV1VCLAttributes(service *gofastly.ServiceDetail, n }) if err != nil { - return fmt.Errorf("[ERR] Error looking up VCL for (%s), version (%s): %s", service.Name, service.ActiveVersion.Number, err) + return fmt.Errorf("[ERR] Error looking up VCL for (%s), version (%v): %s", service.Name, service.ActiveVersion.Number, err) } if len(vclList) != vclCount { diff --git a/builtin/providers/gitlab/config.go b/builtin/providers/gitlab/config.go new file mode 100644 index 000000000..288f7ba6a --- /dev/null +++ b/builtin/providers/gitlab/config.go @@ -0,0 +1,31 @@ +package gitlab + +import ( + "github.com/xanzy/go-gitlab" +) + +// Config is per-provider, specifies where to connect to gitlab +type Config struct { + Token string + BaseURL string +} + +// Client returns a *gitlab.Client to interact with the configured gitlab instance +func (c *Config) Client() (interface{}, error) { + client := gitlab.NewClient(nil, c.Token) + if c.BaseURL != "" { + err := client.SetBaseURL(c.BaseURL) + if err != nil { + // The BaseURL supplied wasn't valid, bail. + return nil, err + } + } + + // Test the credentials by checking we can get information about the authenticated user. + _, _, err := client.Users.CurrentUser() + if err != nil { + return nil, err + } + + return client, nil +} diff --git a/builtin/providers/gitlab/provider.go b/builtin/providers/gitlab/provider.go new file mode 100644 index 000000000..4dfe07f6c --- /dev/null +++ b/builtin/providers/gitlab/provider.go @@ -0,0 +1,52 @@ +package gitlab + +import ( + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +// Provider returns a terraform.ResourceProvider. +func Provider() terraform.ResourceProvider { + + // The actual provider + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "token": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("GITLAB_TOKEN", nil), + Description: descriptions["token"], + }, + "base_url": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("GITLAB_BASE_URL", ""), + Description: descriptions["base_url"], + }, + }, + ResourcesMap: map[string]*schema.Resource{ + "gitlab_project": resourceGitlabProject(), + }, + + ConfigureFunc: providerConfigure, + } +} + +var descriptions map[string]string + +func init() { + descriptions = map[string]string{ + "token": "The OAuth token used to connect to GitLab.", + + "base_url": "The GitLab Base API URL", + } +} + +func providerConfigure(d *schema.ResourceData) (interface{}, error) { + config := Config{ + Token: d.Get("token").(string), + BaseURL: d.Get("base_url").(string), + } + + return config.Client() +} diff --git a/builtin/providers/gitlab/provider_test.go b/builtin/providers/gitlab/provider_test.go new file mode 100644 index 000000000..a28eddb8d --- /dev/null +++ b/builtin/providers/gitlab/provider_test.go @@ -0,0 +1,35 @@ +package gitlab + +import ( + "os" + "testing" + + "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{ + "gitlab": 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("GITLAB_TOKEN"); v == "" { + t.Fatal("GITLAB_TOKEN must be set for acceptance tests") + } +} diff --git a/builtin/providers/gitlab/resource_gitlab_project.go b/builtin/providers/gitlab/resource_gitlab_project.go new file mode 100644 index 000000000..e76c2b1ad --- /dev/null +++ b/builtin/providers/gitlab/resource_gitlab_project.go @@ -0,0 +1,192 @@ +package gitlab + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + gitlab "github.com/xanzy/go-gitlab" +) + +func resourceGitlabProject() *schema.Resource { + return &schema.Resource{ + Create: resourceGitlabProjectCreate, + Read: resourceGitlabProjectRead, + Update: resourceGitlabProjectUpdate, + Delete: resourceGitlabProjectDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "default_branch": { + Type: schema.TypeString, + Optional: true, + }, + "issues_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "merge_requests_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "wiki_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "snippets_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "visibility_level": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"private", "internal", "public"}, true), + Default: "private", + }, + + "ssh_url_to_repo": { + Type: schema.TypeString, + Computed: true, + }, + "http_url_to_repo": { + Type: schema.TypeString, + Computed: true, + }, + "web_url": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceGitlabProjectSetToState(d *schema.ResourceData, project *gitlab.Project) { + d.Set("name", project.Name) + d.Set("description", project.Description) + d.Set("default_branch", project.DefaultBranch) + d.Set("issues_enabled", project.IssuesEnabled) + d.Set("merge_requests_enabled", project.MergeRequestsEnabled) + d.Set("wiki_enabled", project.WikiEnabled) + d.Set("snippets_enabled", project.SnippetsEnabled) + d.Set("visibility_level", visibilityLevelToString(project.VisibilityLevel)) + + d.Set("ssh_url_to_repo", project.SSHURLToRepo) + d.Set("http_url_to_repo", project.HTTPURLToRepo) + d.Set("web_url", project.WebURL) +} + +func resourceGitlabProjectCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*gitlab.Client) + options := &gitlab.CreateProjectOptions{ + Name: gitlab.String(d.Get("name").(string)), + IssuesEnabled: gitlab.Bool(d.Get("issues_enabled").(bool)), + MergeRequestsEnabled: gitlab.Bool(d.Get("merge_requests_enabled").(bool)), + WikiEnabled: gitlab.Bool(d.Get("wiki_enabled").(bool)), + SnippetsEnabled: gitlab.Bool(d.Get("snippets_enabled").(bool)), + } + + if v, ok := d.GetOk("description"); ok { + options.Description = gitlab.String(v.(string)) + } + + if v, ok := d.GetOk("visibility_level"); ok { + options.VisibilityLevel = stringToVisibilityLevel(v.(string)) + } + + log.Printf("[DEBUG] create gitlab project %q", options.Name) + + project, _, err := client.Projects.CreateProject(options) + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("%d", project.ID)) + + return resourceGitlabProjectRead(d, meta) +} + +func resourceGitlabProjectRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*gitlab.Client) + log.Printf("[DEBUG] read gitlab project %s", d.Id()) + + project, response, err := client.Projects.GetProject(d.Id()) + if err != nil { + if response.StatusCode == 404 { + log.Printf("[WARN] removing project %s from state because it no longer exists in gitlab", d.Id()) + d.SetId("") + return nil + } + + return err + } + + resourceGitlabProjectSetToState(d, project) + return nil +} + +func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*gitlab.Client) + + options := &gitlab.EditProjectOptions{} + + if d.HasChange("name") { + options.Name = gitlab.String(d.Get("name").(string)) + } + + if d.HasChange("description") { + options.Description = gitlab.String(d.Get("description").(string)) + } + + if d.HasChange("default_branch") { + options.DefaultBranch = gitlab.String(d.Get("description").(string)) + } + + if d.HasChange("visibility_level") { + options.VisibilityLevel = stringToVisibilityLevel(d.Get("visibility_level").(string)) + } + + if d.HasChange("issues_enabled") { + options.IssuesEnabled = gitlab.Bool(d.Get("issues_enabled").(bool)) + } + + if d.HasChange("merge_requests_enabled") { + options.MergeRequestsEnabled = gitlab.Bool(d.Get("merge_requests_enabled").(bool)) + } + + if d.HasChange("wiki_enabled") { + options.WikiEnabled = gitlab.Bool(d.Get("wiki_enabled").(bool)) + } + + if d.HasChange("snippets_enabled") { + options.SnippetsEnabled = gitlab.Bool(d.Get("snippets_enabled").(bool)) + } + + log.Printf("[DEBUG] update gitlab project %s", d.Id()) + + _, _, err := client.Projects.EditProject(d.Id(), options) + if err != nil { + return err + } + + return resourceGitlabProjectRead(d, meta) +} + +func resourceGitlabProjectDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*gitlab.Client) + log.Printf("[DEBUG] Delete gitlab project %s", d.Id()) + + _, err := client.Projects.DeleteProject(d.Id()) + return err +} diff --git a/builtin/providers/gitlab/resource_gitlab_project_test.go b/builtin/providers/gitlab/resource_gitlab_project_test.go new file mode 100644 index 000000000..52083b0be --- /dev/null +++ b/builtin/providers/gitlab/resource_gitlab_project_test.go @@ -0,0 +1,191 @@ +package gitlab + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/xanzy/go-gitlab" +) + +func TestAccGitlabProject_basic(t *testing.T) { + var project gitlab.Project + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGitlabProjectDestroy, + Steps: []resource.TestStep{ + // Create a project with all the features on + { + Config: testAccGitlabProjectConfig(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckGitlabProjectExists("gitlab_project.foo", &project), + testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ + Name: fmt.Sprintf("foo-%d", rInt), + Description: "Terraform acceptance tests", + IssuesEnabled: true, + MergeRequestsEnabled: true, + WikiEnabled: true, + SnippetsEnabled: true, + VisibilityLevel: 20, + }), + ), + }, + // Update the project to turn the features off + { + Config: testAccGitlabProjectUpdateConfig(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckGitlabProjectExists("gitlab_project.foo", &project), + testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ + Name: fmt.Sprintf("foo-%d", rInt), + Description: "Terraform acceptance tests!", + VisibilityLevel: 20, + }), + ), + }, + //Update the project to turn the features on again + { + Config: testAccGitlabProjectConfig(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckGitlabProjectExists("gitlab_project.foo", &project), + testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ + Name: fmt.Sprintf("foo-%d", rInt), + Description: "Terraform acceptance tests", + IssuesEnabled: true, + MergeRequestsEnabled: true, + WikiEnabled: true, + SnippetsEnabled: true, + VisibilityLevel: 20, + }), + ), + }, + }, + }) +} + +func testAccCheckGitlabProjectExists(n string, project *gitlab.Project) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not Found: %s", n) + } + + repoName := rs.Primary.ID + if repoName == "" { + return fmt.Errorf("No project ID is set") + } + conn := testAccProvider.Meta().(*gitlab.Client) + + gotProject, _, err := conn.Projects.GetProject(repoName) + if err != nil { + return err + } + *project = *gotProject + return nil + } +} + +type testAccGitlabProjectExpectedAttributes struct { + Name string + Description string + DefaultBranch string + IssuesEnabled bool + MergeRequestsEnabled bool + WikiEnabled bool + SnippetsEnabled bool + VisibilityLevel gitlab.VisibilityLevelValue +} + +func testAccCheckGitlabProjectAttributes(project *gitlab.Project, want *testAccGitlabProjectExpectedAttributes) resource.TestCheckFunc { + return func(s *terraform.State) error { + if project.Name != want.Name { + return fmt.Errorf("got repo %q; want %q", project.Name, want.Name) + } + if project.Description != want.Description { + return fmt.Errorf("got description %q; want %q", project.Description, want.Description) + } + + if project.DefaultBranch != want.DefaultBranch { + return fmt.Errorf("got default_branch %q; want %q", project.DefaultBranch, want.DefaultBranch) + } + + if project.IssuesEnabled != want.IssuesEnabled { + return fmt.Errorf("got issues_enabled %t; want %t", project.IssuesEnabled, want.IssuesEnabled) + } + + if project.MergeRequestsEnabled != want.MergeRequestsEnabled { + return fmt.Errorf("got merge_requests_enabled %t; want %t", project.MergeRequestsEnabled, want.MergeRequestsEnabled) + } + + if project.WikiEnabled != want.WikiEnabled { + return fmt.Errorf("got wiki_enabled %t; want %t", project.WikiEnabled, want.WikiEnabled) + } + + if project.SnippetsEnabled != want.SnippetsEnabled { + return fmt.Errorf("got snippets_enabled %t; want %t", project.SnippetsEnabled, want.SnippetsEnabled) + } + + if project.VisibilityLevel != want.VisibilityLevel { + return fmt.Errorf("got default branch %q; want %q", project.VisibilityLevel, want.VisibilityLevel) + } + + return nil + } +} + +func testAccCheckGitlabProjectDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*gitlab.Client) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "gitlab_project" { + continue + } + + gotRepo, resp, err := conn.Projects.GetProject(rs.Primary.ID) + if err == nil { + if gotRepo != nil && fmt.Sprintf("%d", gotRepo.ID) == rs.Primary.ID { + return fmt.Errorf("Repository still exists") + } + } + if resp.StatusCode != 404 { + return err + } + return nil + } + return nil +} + +func testAccGitlabProjectConfig(rInt int) string { + return fmt.Sprintf(` +resource "gitlab_project" "foo" { + name = "foo-%d" + description = "Terraform acceptance tests" + + # So that acceptance tests can be run in a gitlab organization + # with no billing + visibility_level = "public" +} + `, rInt) +} + +func testAccGitlabProjectUpdateConfig(rInt int) string { + return fmt.Sprintf(` +resource "gitlab_project" "foo" { + name = "foo-%d" + description = "Terraform acceptance tests!" + + # So that acceptance tests can be run in a gitlab organization + # with no billing + visibility_level = "public" + + issues_enabled = false + merge_requests_enabled = false + wiki_enabled = false + snippets_enabled = false +} + `, rInt) +} diff --git a/builtin/providers/gitlab/util.go b/builtin/providers/gitlab/util.go new file mode 100644 index 000000000..942e30852 --- /dev/null +++ b/builtin/providers/gitlab/util.go @@ -0,0 +1,54 @@ +package gitlab + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" + gitlab "github.com/xanzy/go-gitlab" +) + +// copied from ../github/util.go +func validateValueFunc(values []string) schema.SchemaValidateFunc { + return func(v interface{}, k string) (we []string, errors []error) { + value := v.(string) + valid := false + for _, role := range values { + if value == role { + valid = true + break + } + } + + if !valid { + errors = append(errors, fmt.Errorf("%s is an invalid value for argument %s", value, k)) + } + return + } +} + +func stringToVisibilityLevel(s string) *gitlab.VisibilityLevelValue { + lookup := map[string]gitlab.VisibilityLevelValue{ + "private": gitlab.PrivateVisibility, + "internal": gitlab.InternalVisibility, + "public": gitlab.PublicVisibility, + } + + value, ok := lookup[s] + if !ok { + return nil + } + return &value +} + +func visibilityLevelToString(v gitlab.VisibilityLevelValue) *string { + lookup := map[gitlab.VisibilityLevelValue]string{ + gitlab.PrivateVisibility: "private", + gitlab.InternalVisibility: "internal", + gitlab.PublicVisibility: "public", + } + value, ok := lookup[v] + if !ok { + return nil + } + return &value +} diff --git a/builtin/providers/gitlab/util_test.go b/builtin/providers/gitlab/util_test.go new file mode 100644 index 000000000..465eec73c --- /dev/null +++ b/builtin/providers/gitlab/util_test.go @@ -0,0 +1,65 @@ +package gitlab + +import ( + "testing" + + "github.com/xanzy/go-gitlab" +) + +func TestGitlab_validation(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + Value: "invalid", + ErrCount: 1, + }, + { + Value: "valid_one", + ErrCount: 0, + }, + { + Value: "valid_two", + ErrCount: 0, + }, + } + + validationFunc := validateValueFunc([]string{"valid_one", "valid_two"}) + + for _, tc := range cases { + _, errors := validationFunc(tc.Value, "test_arg") + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected 1 validation error") + } + } +} + +func TestGitlab_visbilityHelpers(t *testing.T) { + cases := []struct { + String string + Level gitlab.VisibilityLevelValue + }{ + { + String: "private", + Level: gitlab.PrivateVisibility, + }, + { + String: "public", + Level: gitlab.PublicVisibility, + }, + } + + for _, tc := range cases { + level := stringToVisibilityLevel(tc.String) + if level == nil || *level != tc.Level { + t.Fatalf("got %v expected %v", level, tc.Level) + } + + sv := visibilityLevelToString(tc.Level) + if sv == nil || *sv != tc.String { + t.Fatalf("got %v expected %v", sv, tc.String) + } + } +} diff --git a/builtin/providers/google/resource_compute_forwarding_rule.go b/builtin/providers/google/resource_compute_forwarding_rule.go index 99684560d..529588fdc 100644 --- a/builtin/providers/google/resource_compute_forwarding_rule.go +++ b/builtin/providers/google/resource_compute_forwarding_rule.go @@ -90,6 +90,7 @@ func resourceComputeForwardingRule() *schema.Resource { Optional: true, ForceNew: true, Set: schema.HashString, + MaxItems: 5, }, "project": &schema.Schema{ diff --git a/builtin/providers/google/resource_compute_instance.go b/builtin/providers/google/resource_compute_instance.go index 46daaf315..c1bb4e77b 100644 --- a/builtin/providers/google/resource_compute_instance.go +++ b/builtin/providers/google/resource_compute_instance.go @@ -28,7 +28,7 @@ func resourceComputeInstance() *schema.Resource { Schema: map[string]*schema.Schema{ "disk": &schema.Schema{ Type: schema.TypeList, - Required: true, + Optional: true, ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -91,6 +91,40 @@ func resourceComputeInstance() *schema.Resource { }, }, + // Preferred way of adding persistent disks to an instance. + // Use this instead of `disk` when possible. + "attached_disk": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + ForceNew: true, // TODO(danawillow): Remove this, support attaching/detaching + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "source": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "device_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "disk_encryption_key_raw": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ForceNew: true, + }, + + "disk_encryption_key_sha256": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "machine_type": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -371,7 +405,11 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err // Build up the list of disks disksCount := d.Get("disk.#").(int) - disks := make([]*compute.AttachedDisk, 0, disksCount) + attachedDisksCount := d.Get("attached_disk.#").(int) + if disksCount+attachedDisksCount == 0 { + return fmt.Errorf("At least one disk or attached_disk must be set") + } + disks := make([]*compute.AttachedDisk, 0, disksCount+attachedDisksCount) for i := 0; i < disksCount; i++ { prefix := fmt.Sprintf("disk.%d", i) @@ -457,6 +495,28 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err disks = append(disks, &disk) } + for i := 0; i < attachedDisksCount; i++ { + prefix := fmt.Sprintf("attached_disk.%d", i) + disk := compute.AttachedDisk{ + Source: d.Get(prefix + ".source").(string), + AutoDelete: false, // Don't allow autodelete; let terraform handle disk deletion + } + + disk.Boot = i == 0 && disksCount == 0 // TODO(danawillow): This is super hacky, let's just add a boot field. + + if v, ok := d.GetOk(prefix + ".device_name"); ok { + disk.DeviceName = v.(string) + } + + if v, ok := d.GetOk(prefix + ".disk_encryption_key_raw"); ok { + disk.DiskEncryptionKey = &compute.CustomerEncryptionKey{ + RawKey: v.(string), + } + } + + disks = append(disks, &disk) + } + networksCount := d.Get("network.#").(int) networkInterfacesCount := d.Get("network_interface.#").(int) @@ -791,24 +851,54 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error d.Set("tags_fingerprint", instance.Tags.Fingerprint) } - disks := make([]map[string]interface{}, 0, 1) - for i, disk := range instance.Disks { - di := map[string]interface{}{ - "disk": d.Get(fmt.Sprintf("disk.%d.disk", i)), - "image": d.Get(fmt.Sprintf("disk.%d.image", i)), - "type": d.Get(fmt.Sprintf("disk.%d.type", i)), - "scratch": d.Get(fmt.Sprintf("disk.%d.scratch", i)), - "auto_delete": d.Get(fmt.Sprintf("disk.%d.auto_delete", i)), - "size": d.Get(fmt.Sprintf("disk.%d.size", i)), - "device_name": d.Get(fmt.Sprintf("disk.%d.device_name", i)), - "disk_encryption_key_raw": d.Get(fmt.Sprintf("disk.%d.disk_encryption_key_raw", i)), + disksCount := d.Get("disk.#").(int) + attachedDisksCount := d.Get("attached_disk.#").(int) + disks := make([]map[string]interface{}, 0, disksCount) + attachedDisks := make([]map[string]interface{}, 0, attachedDisksCount) + + if expectedDisks := disksCount + attachedDisksCount; len(instance.Disks) != expectedDisks { + return fmt.Errorf("Expected %d disks, API returned %d", expectedDisks, len(instance.Disks)) + } + + attachedDiskSources := make(map[string]struct{}, attachedDisksCount) + for i := 0; i < attachedDisksCount; i++ { + attachedDiskSources[d.Get(fmt.Sprintf("attached_disk.%d.source", i)).(string)] = struct{}{} + } + + dIndex := 0 + adIndex := 0 + for _, disk := range instance.Disks { + if _, ok := attachedDiskSources[disk.Source]; !ok { + di := map[string]interface{}{ + "disk": d.Get(fmt.Sprintf("disk.%d.disk", dIndex)), + "image": d.Get(fmt.Sprintf("disk.%d.image", dIndex)), + "type": d.Get(fmt.Sprintf("disk.%d.type", dIndex)), + "scratch": d.Get(fmt.Sprintf("disk.%d.scratch", dIndex)), + "auto_delete": d.Get(fmt.Sprintf("disk.%d.auto_delete", dIndex)), + "size": d.Get(fmt.Sprintf("disk.%d.size", dIndex)), + "device_name": d.Get(fmt.Sprintf("disk.%d.device_name", dIndex)), + "disk_encryption_key_raw": d.Get(fmt.Sprintf("disk.%d.disk_encryption_key_raw", dIndex)), + } + if disk.DiskEncryptionKey != nil && disk.DiskEncryptionKey.Sha256 != "" { + di["disk_encryption_key_sha256"] = disk.DiskEncryptionKey.Sha256 + } + disks = append(disks, di) + dIndex++ + } else { + di := map[string]interface{}{ + "source": disk.Source, + "device_name": disk.DeviceName, + "disk_encryption_key_raw": d.Get(fmt.Sprintf("attached_disk.%d.disk_encryption_key_raw", adIndex)), + } + if disk.DiskEncryptionKey != nil && disk.DiskEncryptionKey.Sha256 != "" { + di["disk_encryption_key_sha256"] = disk.DiskEncryptionKey.Sha256 + } + attachedDisks = append(attachedDisks, di) + adIndex++ } - if disk.DiskEncryptionKey != nil && disk.DiskEncryptionKey.Sha256 != "" { - di["disk_encryption_key_sha256"] = disk.DiskEncryptionKey.Sha256 - } - disks = append(disks, di) } d.Set("disk", disks) + d.Set("attached_disk", attachedDisks) d.Set("self_link", instance.SelfLink) d.SetId(instance.Name) diff --git a/builtin/providers/google/resource_compute_instance_template_test.go b/builtin/providers/google/resource_compute_instance_template_test.go index e287d32e2..6388a1dfe 100644 --- a/builtin/providers/google/resource_compute_instance_template_test.go +++ b/builtin/providers/google/resource_compute_instance_template_test.go @@ -27,7 +27,7 @@ func TestAccComputeInstanceTemplate_basic(t *testing.T) { "google_compute_instance_template.foobar", &instanceTemplate), testAccCheckComputeInstanceTemplateTag(&instanceTemplate, "foo"), testAccCheckComputeInstanceTemplateMetadata(&instanceTemplate, "foo", "bar"), - testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-8-jessie-v20160803", true, true), + testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "projects/debian-cloud/global/images/debian-8-jessie-v20160803", true, true), ), }, }, @@ -67,7 +67,7 @@ func TestAccComputeInstanceTemplate_disks(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckComputeInstanceTemplateExists( "google_compute_instance_template.foobar", &instanceTemplate), - testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-8-jessie-v20160803", true, true), + testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "projects/debian-cloud/global/images/debian-8-jessie-v20160803", true, true), testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "terraform-test-foobar", false, false), ), }, diff --git a/builtin/providers/google/resource_compute_instance_test.go b/builtin/providers/google/resource_compute_instance_test.go index a4d52d872..e91368e24 100644 --- a/builtin/providers/google/resource_compute_instance_test.go +++ b/builtin/providers/google/resource_compute_instance_test.go @@ -244,6 +244,44 @@ func TestAccComputeInstance_diskEncryption(t *testing.T) { }) } +func TestAccComputeInstance_attachedDisk(t *testing.T) { + var instance compute.Instance + var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) + var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeInstance_attachedDisk(diskName, instanceName), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeInstanceExists( + "google_compute_instance.foobar", &instance), + testAccCheckComputeInstanceDisk(&instance, diskName, false, true), + ), + }, + }, + }) +} + +func TestAccComputeInstance_noDisk(t *testing.T) { + var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeInstance_noDisk(instanceName), + ExpectError: regexp.MustCompile("At least one disk or attached_disk must be set"), + }, + }, + }) +} + func TestAccComputeInstance_local_ssd(t *testing.T) { var instance compute.Instance var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10)) @@ -1121,6 +1159,51 @@ func testAccComputeInstance_disks_encryption(disk, instance string) string { }`, disk, instance) } +func testAccComputeInstance_attachedDisk(disk, instance string) string { + return fmt.Sprintf(` + resource "google_compute_disk" "foobar" { + name = "%s" + size = 10 + type = "pd-ssd" + zone = "us-central1-a" + } + + resource "google_compute_instance" "foobar" { + name = "%s" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + attached_disk { + source = "${google_compute_disk.foobar.self_link}" + } + + network_interface { + network = "default" + } + + metadata { + foo = "bar" + } + }`, disk, instance) +} + +func testAccComputeInstance_noDisk(instance string) string { + return fmt.Sprintf(` + resource "google_compute_instance" "foobar" { + name = "%s" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + network_interface { + network = "default" + } + + metadata { + foo = "bar" + } + }`, instance) +} + func testAccComputeInstance_local_ssd(instance string) string { return fmt.Sprintf(` resource "google_compute_instance" "local-ssd" { diff --git a/builtin/providers/google/resource_container_cluster.go b/builtin/providers/google/resource_container_cluster.go index 8b3233111..55805541c 100644 --- a/builtin/providers/google/resource_container_cluster.go +++ b/builtin/providers/google/resource_container_cluster.go @@ -408,14 +408,14 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er addonsConfig := v.([]interface{})[0].(map[string]interface{}) cluster.AddonsConfig = &container.AddonsConfig{} - if v, ok := addonsConfig["http_load_balancing"]; ok { + if v, ok := addonsConfig["http_load_balancing"]; ok && len(v.([]interface{})) > 0 { addon := v.([]interface{})[0].(map[string]interface{}) cluster.AddonsConfig.HttpLoadBalancing = &container.HttpLoadBalancing{ Disabled: addon["disabled"].(bool), } } - if v, ok := addonsConfig["horizontal_pod_autoscaling"]; ok { + if v, ok := addonsConfig["horizontal_pod_autoscaling"]; ok && len(v.([]interface{})) > 0 { addon := v.([]interface{})[0].(map[string]interface{}) cluster.AddonsConfig.HorizontalPodAutoscaling = &container.HorizontalPodAutoscaling{ Disabled: addon["disabled"].(bool), diff --git a/builtin/providers/google/resource_container_cluster_test.go b/builtin/providers/google/resource_container_cluster_test.go index 1c26dfefe..236785e43 100644 --- a/builtin/providers/google/resource_container_cluster_test.go +++ b/builtin/providers/google/resource_container_cluster_test.go @@ -403,7 +403,7 @@ var testAccContainerCluster_withVersion = fmt.Sprintf(` resource "google_container_cluster" "with_version" { name = "cluster-test-%s" zone = "us-central1-a" - node_version = "1.6.0" + node_version = "1.6.1" initial_node_count = 1 master_auth { diff --git a/builtin/providers/heroku/provider.go b/builtin/providers/heroku/provider.go index b6ea2bc98..6a8c9b986 100644 --- a/builtin/providers/heroku/provider.go +++ b/builtin/providers/heroku/provider.go @@ -25,11 +25,12 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "heroku_app": resourceHerokuApp(), "heroku_addon": resourceHerokuAddon(), + "heroku_app": resourceHerokuApp(), + "heroku_cert": resourceHerokuCert(), "heroku_domain": resourceHerokuDomain(), "heroku_drain": resourceHerokuDrain(), - "heroku_cert": resourceHerokuCert(), + "heroku_space": resourceHerokuSpace(), }, ConfigureFunc: providerConfigure, diff --git a/builtin/providers/heroku/resource_heroku_app.go b/builtin/providers/heroku/resource_heroku_app.go index 20a6c9c0d..820296325 100644 --- a/builtin/providers/heroku/resource_heroku_app.go +++ b/builtin/providers/heroku/resource_heroku_app.go @@ -16,6 +16,7 @@ import ( type herokuApplication struct { Name string Region string + Space string Stack string GitURL string WebURL string @@ -30,6 +31,7 @@ type application struct { App *herokuApplication // The heroku application Client *heroku.Service // Client to interact with the heroku API Vars map[string]string // The vars on the application + Buildpacks []string // The application's buildpack names or URLs Organization bool // is the application organization app } @@ -62,6 +64,9 @@ func (a *application) Update() error { a.App.Stack = app.Stack.Name a.App.GitURL = app.GitURL a.App.WebURL = app.WebURL + if app.Space != nil { + a.App.Space = app.Space.Name + } if app.Organization != nil { a.App.OrganizationName = app.Organization.Name } else { @@ -71,6 +76,11 @@ func (a *application) Update() error { } } + a.Buildpacks, err = retrieveBuildpacks(a.Id, a.Client) + if err != nil { + errs = append(errs, err) + } + a.Vars, err = retrieveConfigVars(a.Id, a.Client) if err != nil { errs = append(errs, err) @@ -96,6 +106,12 @@ func resourceHerokuApp() *schema.Resource { Required: true, }, + "space": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "region": { Type: schema.TypeString, Required: true, @@ -109,6 +125,14 @@ func resourceHerokuApp() *schema.Resource { ForceNew: true, }, + "buildpacks": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "config_vars": { Type: schema.TypeList, Optional: true, @@ -208,11 +232,8 @@ func resourceHerokuAppCreate(d *schema.ResourceData, meta interface{}) error { d.SetId(a.Name) log.Printf("[INFO] App ID: %s", d.Id()) - if v, ok := d.GetOk("config_vars"); ok { - err = updateConfigVars(d.Id(), client, nil, v.([]interface{})) - if err != nil { - return err - } + if err := performAppPostCreateTasks(d, client); err != nil { + return err } return resourceHerokuAppRead(d, meta) @@ -257,6 +278,11 @@ func resourceHerokuOrgAppCreate(d *schema.ResourceData, meta interface{}) error log.Printf("[DEBUG] App region: %s", vs) opts.Region = &vs } + if v, ok := d.GetOk("space"); ok { + vs := v.(string) + log.Printf("[DEBUG] App space: %s", vs) + opts.Space = &vs + } if v, ok := d.GetOk("stack"); ok { vs := v.(string) log.Printf("[DEBUG] App stack: %s", vs) @@ -272,11 +298,8 @@ func resourceHerokuOrgAppCreate(d *schema.ResourceData, meta interface{}) error d.SetId(a.Name) log.Printf("[INFO] App ID: %s", d.Id()) - if v, ok := d.GetOk("config_vars"); ok { - err = updateConfigVars(d.Id(), client, nil, v.([]interface{})) - if err != nil { - return err - } + if err := performAppPostCreateTasks(d, client); err != nil { + return err } return resourceHerokuAppRead(d, meta) @@ -293,6 +316,9 @@ func resourceHerokuAppRead(d *schema.ResourceData, meta interface{}) error { } } + // Only track buildpacks when set in the configuration. + _, buildpacksConfigured := d.GetOk("buildpacks") + organizationApp := isOrganizationApp(d) // Only set the config_vars that we have set in the configuration. @@ -317,9 +343,14 @@ func resourceHerokuAppRead(d *schema.ResourceData, meta interface{}) error { d.Set("region", app.App.Region) d.Set("git_url", app.App.GitURL) d.Set("web_url", app.App.WebURL) + if buildpacksConfigured { + d.Set("buildpacks", app.Buildpacks) + } d.Set("config_vars", configVarsValue) d.Set("all_config_vars", app.Vars) if organizationApp { + d.Set("space", app.App.Space) + orgDetails := map[string]interface{}{ "name": app.App.OrganizationName, "locked": app.App.Locked, @@ -374,6 +405,13 @@ func resourceHerokuAppUpdate(d *schema.ResourceData, meta interface{}) error { } } + if d.HasChange("buildpacks") { + err := updateBuildpacks(d.Id(), client, d.Get("buildpacks").([]interface{})) + if err != nil { + return err + } + } + return resourceHerokuAppRead(d, meta) } @@ -402,6 +440,21 @@ func resourceHerokuAppRetrieve(id string, organization bool, client *heroku.Serv return &app, nil } +func retrieveBuildpacks(id string, client *heroku.Service) ([]string, error) { + results, err := client.BuildpackInstallationList(context.TODO(), id, nil) + + if err != nil { + return nil, err + } + + buildpacks := []string{} + for _, installation := range results { + buildpacks = append(buildpacks, installation.Buildpack.Name) + } + + return buildpacks, nil +} + func retrieveConfigVars(id string, client *heroku.Service) (map[string]string, error) { vars, err := client.ConfigVarInfoForApp(context.TODO(), id) @@ -450,3 +503,41 @@ func updateConfigVars( return nil } + +func updateBuildpacks(id string, client *heroku.Service, v []interface{}) error { + opts := heroku.BuildpackInstallationUpdateOpts{ + Updates: []struct { + Buildpack string `json:"buildpack" url:"buildpack,key"` + }{}} + + for _, buildpack := range v { + opts.Updates = append(opts.Updates, struct { + Buildpack string `json:"buildpack" url:"buildpack,key"` + }{ + Buildpack: buildpack.(string), + }) + } + + if _, err := client.BuildpackInstallationUpdate(context.TODO(), id, opts); err != nil { + return fmt.Errorf("Error updating buildpacks: %s", err) + } + + return nil +} + +// performAppPostCreateTasks performs post-create tasks common to both org and non-org apps. +func performAppPostCreateTasks(d *schema.ResourceData, client *heroku.Service) error { + if v, ok := d.GetOk("config_vars"); ok { + if err := updateConfigVars(d.Id(), client, nil, v.([]interface{})); err != nil { + return err + } + } + + if v, ok := d.GetOk("buildpacks"); ok { + if err := updateBuildpacks(d.Id(), client, v.([]interface{})); err != nil { + return err + } + } + + return nil +} diff --git a/builtin/providers/heroku/resource_heroku_app_test.go b/builtin/providers/heroku/resource_heroku_app_test.go index caeade8f2..5888271af 100644 --- a/builtin/providers/heroku/resource_heroku_app_test.go +++ b/builtin/providers/heroku/resource_heroku_app_test.go @@ -109,6 +109,75 @@ func TestAccHerokuApp_NukeVars(t *testing.T) { }) } +func TestAccHerokuApp_Buildpacks(t *testing.T) { + var app heroku.AppInfoResult + appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckHerokuAppDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckHerokuAppConfig_go(appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuAppExists("heroku_app.foobar", &app), + testAccCheckHerokuAppBuildpacks(appName, false), + resource.TestCheckResourceAttr("heroku_app.foobar", "buildpacks.0", "heroku/go"), + ), + }, + { + Config: testAccCheckHerokuAppConfig_multi(appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuAppExists("heroku_app.foobar", &app), + testAccCheckHerokuAppBuildpacks(appName, true), + resource.TestCheckResourceAttr( + "heroku_app.foobar", "buildpacks.0", "https://github.com/heroku/heroku-buildpack-multi-procfile"), + resource.TestCheckResourceAttr("heroku_app.foobar", "buildpacks.1", "heroku/go"), + ), + }, + { + Config: testAccCheckHerokuAppConfig_no_vars(appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuAppExists("heroku_app.foobar", &app), + testAccCheckHerokuAppNoBuildpacks(appName), + resource.TestCheckNoResourceAttr("heroku_app.foobar", "buildpacks.0"), + ), + }, + }, + }) +} + +func TestAccHerokuApp_ExternallySetBuildpacks(t *testing.T) { + var app heroku.AppInfoResult + appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckHerokuAppDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckHerokuAppConfig_no_vars(appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuAppExists("heroku_app.foobar", &app), + testAccCheckHerokuAppNoBuildpacks(appName), + resource.TestCheckNoResourceAttr("heroku_app.foobar", "buildpacks.0"), + ), + }, + { + PreConfig: testAccInstallUnconfiguredBuildpack(t, appName), + Config: testAccCheckHerokuAppConfig_no_vars(appName), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuAppExists("heroku_app.foobar", &app), + testAccCheckHerokuAppBuildpacks(appName, false), + resource.TestCheckNoResourceAttr("heroku_app.foobar", "buildpacks.0"), + ), + }, + }, + }) +} + func TestAccHerokuApp_Organization(t *testing.T) { var app heroku.OrganizationApp appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) @@ -128,7 +197,37 @@ func TestAccHerokuApp_Organization(t *testing.T) { Config: testAccCheckHerokuAppConfig_organization(appName, org), Check: resource.ComposeTestCheckFunc( testAccCheckHerokuAppExistsOrg("heroku_app.foobar", &app), - testAccCheckHerokuAppAttributesOrg(&app, appName, org), + testAccCheckHerokuAppAttributesOrg(&app, appName, "", org), + ), + }, + }, + }) +} + +func TestAccHerokuApp_Space(t *testing.T) { + var app heroku.OrganizationApp + appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) + org := os.Getenv("HEROKU_ORGANIZATION") + space := os.Getenv("HEROKU_SPACE") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + if org == "" { + t.Skip("HEROKU_ORGANIZATION is not set; skipping test.") + } + if space == "" { + t.Skip("HEROKU_SPACE is not set; skipping test.") + } + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckHerokuAppDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckHerokuAppConfig_space(appName, space, org), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuAppExistsOrg("heroku_app.foobar", &app), + testAccCheckHerokuAppAttributesOrg(&app, appName, space, org), ), }, }, @@ -230,14 +329,76 @@ func testAccCheckHerokuAppAttributesNoVars(app *heroku.AppInfoResult, appName st } } -func testAccCheckHerokuAppAttributesOrg(app *heroku.OrganizationApp, appName string, org string) resource.TestCheckFunc { +func testAccCheckHerokuAppBuildpacks(appName string, multi bool) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*heroku.Service) - if app.Region.Name != "us" { + results, err := client.BuildpackInstallationList(context.TODO(), appName, nil) + if err != nil { + return err + } + + buildpacks := []string{} + for _, installation := range results { + buildpacks = append(buildpacks, installation.Buildpack.Name) + } + + if multi { + herokuMulti := "https://github.com/heroku/heroku-buildpack-multi-procfile" + if len(buildpacks) != 2 || buildpacks[0] != herokuMulti || buildpacks[1] != "heroku/go" { + return fmt.Errorf("Bad buildpacks: %v", buildpacks) + } + + return nil + } + + if len(buildpacks) != 1 || buildpacks[0] != "heroku/go" { + return fmt.Errorf("Bad buildpacks: %v", buildpacks) + } + + return nil + } +} + +func testAccCheckHerokuAppNoBuildpacks(appName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*heroku.Service) + + results, err := client.BuildpackInstallationList(context.TODO(), appName, nil) + if err != nil { + return err + } + + buildpacks := []string{} + for _, installation := range results { + buildpacks = append(buildpacks, installation.Buildpack.Name) + } + + if len(buildpacks) != 0 { + return fmt.Errorf("Bad buildpacks: %v", buildpacks) + } + + return nil + } +} + +func testAccCheckHerokuAppAttributesOrg(app *heroku.OrganizationApp, appName, space, org string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*heroku.Service) + + if app.Region.Name != "us" && app.Region.Name != "virginia" { return fmt.Errorf("Bad region: %s", app.Region.Name) } + var appSpace string + if app.Space != nil { + appSpace = app.Space.Name + } + + if appSpace != space { + return fmt.Errorf("Bad space: %s", appSpace) + } + if app.Stack.Name != "cedar-14" { return fmt.Errorf("Bad stack: %s", app.Stack.Name) } @@ -323,6 +484,25 @@ func testAccCheckHerokuAppExistsOrg(n string, app *heroku.OrganizationApp) resou } } +func testAccInstallUnconfiguredBuildpack(t *testing.T, appName string) func() { + return func() { + client := testAccProvider.Meta().(*heroku.Service) + + opts := heroku.BuildpackInstallationUpdateOpts{ + Updates: []struct { + Buildpack string `json:"buildpack" url:"buildpack,key"` + }{ + {Buildpack: "heroku/go"}, + }, + } + + _, err := client.BuildpackInstallationUpdate(context.TODO(), appName, opts) + if err != nil { + t.Fatalf("Error updating buildpacks: %s", err) + } + } +} + func testAccCheckHerokuAppConfig_basic(appName string) string { return fmt.Sprintf(` resource "heroku_app" "foobar" { @@ -335,6 +515,29 @@ resource "heroku_app" "foobar" { }`, appName) } +func testAccCheckHerokuAppConfig_go(appName string) string { + return fmt.Sprintf(` +resource "heroku_app" "foobar" { + name = "%s" + region = "us" + + buildpacks = ["heroku/go"] +}`, appName) +} + +func testAccCheckHerokuAppConfig_multi(appName string) string { + return fmt.Sprintf(` +resource "heroku_app" "foobar" { + name = "%s" + region = "us" + + buildpacks = [ + "https://github.com/heroku/heroku-buildpack-multi-procfile", + "heroku/go" + ] +}`, appName) +} + func testAccCheckHerokuAppConfig_updated(appName string) string { return fmt.Sprintf(` resource "heroku_app" "foobar" { @@ -371,3 +574,20 @@ resource "heroku_app" "foobar" { } }`, appName, org) } + +func testAccCheckHerokuAppConfig_space(appName, space, org string) string { + return fmt.Sprintf(` +resource "heroku_app" "foobar" { + name = "%s" + space = "%s" + region = "virginia" + + organization { + name = "%s" + } + + config_vars { + FOO = "bar" + } +}`, appName, space, org) +} diff --git a/builtin/providers/heroku/resource_heroku_space.go b/builtin/providers/heroku/resource_heroku_space.go new file mode 100644 index 000000000..3e90fffbb --- /dev/null +++ b/builtin/providers/heroku/resource_heroku_space.go @@ -0,0 +1,117 @@ +package heroku + +import ( + "context" + "log" + + heroku "github.com/cyberdelia/heroku-go/v3" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceHerokuSpace() *schema.Resource { + return &schema.Resource{ + Create: resourceHerokuSpaceCreate, + Read: resourceHerokuSpaceRead, + Update: resourceHerokuSpaceUpdate, + Delete: resourceHerokuSpaceDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "organization": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "region": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func resourceHerokuSpaceCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*heroku.Service) + + opts := heroku.SpaceCreateOpts{} + opts.Name = d.Get("name").(string) + opts.Organization = d.Get("organization").(string) + + if v, ok := d.GetOk("region"); ok { + vs := v.(string) + opts.Region = &vs + } + + space, err := client.SpaceCreate(context.TODO(), opts) + if err != nil { + return err + } + + d.SetId(space.ID) + log.Printf("[INFO] Space ID: %s", d.Id()) + + // The type conversion here can be dropped when the vendored version of + // heroku-go is updated. + setSpaceAttributes(d, (*heroku.Space)(space)) + return nil +} + +func resourceHerokuSpaceRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*heroku.Service) + + space, err := client.SpaceInfo(context.TODO(), d.Id()) + if err != nil { + return err + } + + // The type conversion here can be dropped when the vendored version of + // heroku-go is updated. + setSpaceAttributes(d, (*heroku.Space)(space)) + return nil +} + +func resourceHerokuSpaceUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*heroku.Service) + + if !d.HasChange("name") { + return nil + } + + name := d.Get("name").(string) + opts := heroku.SpaceUpdateOpts{Name: &name} + + space, err := client.SpaceUpdate(context.TODO(), d.Id(), opts) + if err != nil { + return err + } + + // The type conversion here can be dropped when the vendored version of + // heroku-go is updated. + setSpaceAttributes(d, (*heroku.Space)(space)) + return nil +} + +func setSpaceAttributes(d *schema.ResourceData, space *heroku.Space) { + d.Set("name", space.Name) + d.Set("organization", space.Organization.Name) + d.Set("region", space.Region.Name) +} + +func resourceHerokuSpaceDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*heroku.Service) + + log.Printf("[INFO] Deleting space: %s", d.Id()) + _, err := client.SpaceDelete(context.TODO(), d.Id()) + if err != nil { + return err + } + + d.SetId("") + return nil +} diff --git a/builtin/providers/heroku/resource_heroku_space_test.go b/builtin/providers/heroku/resource_heroku_space_test.go new file mode 100644 index 000000000..72a2ed0c5 --- /dev/null +++ b/builtin/providers/heroku/resource_heroku_space_test.go @@ -0,0 +1,114 @@ +package heroku + +import ( + "context" + "fmt" + "os" + "testing" + + heroku "github.com/cyberdelia/heroku-go/v3" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccHerokuSpace_Basic(t *testing.T) { + var space heroku.SpaceInfoResult + spaceName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) + spaceName2 := fmt.Sprintf("tftest-%s", acctest.RandString(10)) + org := os.Getenv("HEROKU_ORGANIZATION") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + if org == "" { + t.Skip("HEROKU_ORGANIZATION is not set; skipping test.") + } + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckHerokuSpaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckHerokuSpaceConfig_basic(spaceName, org), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuSpaceExists("heroku_space.foobar", &space), + testAccCheckHerokuSpaceAttributes(&space, spaceName), + ), + }, + { + Config: testAccCheckHerokuSpaceConfig_basic(spaceName2, org), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuSpaceExists("heroku_space.foobar", &space), + testAccCheckHerokuSpaceAttributes(&space, spaceName2), + ), + }, + }, + }) +} + +func testAccCheckHerokuSpaceConfig_basic(spaceName, orgName string) string { + return fmt.Sprintf(` +resource "heroku_space" "foobar" { + name = "%s" + organization = "%s" + region = "virginia" +} +`, spaceName, orgName) +} + +func testAccCheckHerokuSpaceExists(n string, space *heroku.SpaceInfoResult) 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 space name set") + } + + client := testAccProvider.Meta().(*heroku.Service) + + foundSpace, err := client.SpaceInfo(context.TODO(), rs.Primary.ID) + if err != nil { + return err + } + + if foundSpace.ID != rs.Primary.ID { + return fmt.Errorf("Space not found") + } + + *space = *foundSpace + + return nil + } +} + +func testAccCheckHerokuSpaceAttributes(space *heroku.SpaceInfoResult, spaceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if space.Name != spaceName { + return fmt.Errorf("Bad name: %s", space.Name) + } + + return nil + } +} + +func testAccCheckHerokuSpaceDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*heroku.Service) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "heroku_space" { + continue + } + + _, err := client.SpaceInfo(context.TODO(), rs.Primary.ID) + + if err == nil { + return fmt.Errorf("Space still exists") + } + } + + return nil +} diff --git a/builtin/providers/ignition/provider.go b/builtin/providers/ignition/provider.go index 6ad832d03..81462e361 100644 --- a/builtin/providers/ignition/provider.go +++ b/builtin/providers/ignition/provider.go @@ -15,6 +15,21 @@ import ( "github.com/hashicorp/terraform/terraform" ) +// globalCache keeps the instances of the internal types of ignition generated +// by the different data resources with the goal to be reused by the +// ignition_config data resource. The key of the maps are a hash of the types +// calculated on the type serialized to JSON. +var globalCache = &cache{ + disks: make(map[string]*types.Disk, 0), + arrays: make(map[string]*types.Raid, 0), + filesystems: make(map[string]*types.Filesystem, 0), + files: make(map[string]*types.File, 0), + systemdUnits: make(map[string]*types.SystemdUnit, 0), + networkdUnits: make(map[string]*types.NetworkdUnit, 0), + users: make(map[string]*types.User, 0), + groups: make(map[string]*types.Group, 0), +} + func Provider() terraform.ResourceProvider { return &schema.Provider{ DataSourcesMap: map[string]*schema.Resource{ @@ -66,18 +81,6 @@ func Provider() terraform.ResourceProvider { resourceGroup(), ), }, - ConfigureFunc: func(*schema.ResourceData) (interface{}, error) { - return &cache{ - disks: make(map[string]*types.Disk, 0), - arrays: make(map[string]*types.Raid, 0), - filesystems: make(map[string]*types.Filesystem, 0), - files: make(map[string]*types.File, 0), - systemdUnits: make(map[string]*types.SystemdUnit, 0), - networkdUnits: make(map[string]*types.NetworkdUnit, 0), - users: make(map[string]*types.User, 0), - groups: make(map[string]*types.Group, 0), - }, nil - }, } } diff --git a/builtin/providers/ignition/resource_ignition_config.go b/builtin/providers/ignition/resource_ignition_config.go index 4df56f79c..c75e50afd 100644 --- a/builtin/providers/ignition/resource_ignition_config.go +++ b/builtin/providers/ignition/resource_ignition_config.go @@ -91,7 +91,7 @@ func resourceConfig() *schema.Resource { } func resourceIgnitionFileRead(d *schema.ResourceData, meta interface{}) error { - rendered, err := renderConfig(d, meta.(*cache)) + rendered, err := renderConfig(d, globalCache) if err != nil { return err } @@ -105,7 +105,7 @@ func resourceIgnitionFileRead(d *schema.ResourceData, meta interface{}) error { } func resourceIgnitionFileExists(d *schema.ResourceData, meta interface{}) (bool, error) { - rendered, err := renderConfig(d, meta.(*cache)) + rendered, err := renderConfig(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_disk.go b/builtin/providers/ignition/resource_ignition_disk.go index 3fa9b947a..8ef6c7e05 100644 --- a/builtin/providers/ignition/resource_ignition_disk.go +++ b/builtin/providers/ignition/resource_ignition_disk.go @@ -59,7 +59,7 @@ func resourceDisk() *schema.Resource { } func resourceDiskRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildDisk(d, meta.(*cache)) + id, err := buildDisk(d, globalCache) if err != nil { return err } @@ -69,7 +69,7 @@ func resourceDiskRead(d *schema.ResourceData, meta interface{}) error { } func resourceDiskExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildDisk(d, meta.(*cache)) + id, err := buildDisk(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_file.go b/builtin/providers/ignition/resource_ignition_file.go index a6f34f2fa..0f73ea6ed 100644 --- a/builtin/providers/ignition/resource_ignition_file.go +++ b/builtin/providers/ignition/resource_ignition_file.go @@ -90,7 +90,7 @@ func resourceFile() *schema.Resource { } func resourceFileRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildFile(d, meta.(*cache)) + id, err := buildFile(d, globalCache) if err != nil { return err } @@ -100,7 +100,7 @@ func resourceFileRead(d *schema.ResourceData, meta interface{}) error { } func resourceFileExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildFile(d, meta.(*cache)) + id, err := buildFile(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_filesystem.go b/builtin/providers/ignition/resource_ignition_filesystem.go index a26c3f700..ce858e80c 100644 --- a/builtin/providers/ignition/resource_ignition_filesystem.go +++ b/builtin/providers/ignition/resource_ignition_filesystem.go @@ -63,7 +63,7 @@ func resourceFilesystem() *schema.Resource { } func resourceFilesystemRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildFilesystem(d, meta.(*cache)) + id, err := buildFilesystem(d, globalCache) if err != nil { return err } @@ -73,7 +73,7 @@ func resourceFilesystemRead(d *schema.ResourceData, meta interface{}) error { } func resourceFilesystemExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildFilesystem(d, meta.(*cache)) + id, err := buildFilesystem(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_group.go b/builtin/providers/ignition/resource_ignition_group.go index 29ebeecd9..125e97e73 100644 --- a/builtin/providers/ignition/resource_ignition_group.go +++ b/builtin/providers/ignition/resource_ignition_group.go @@ -30,7 +30,7 @@ func resourceGroup() *schema.Resource { } func resourceGroupRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildGroup(d, meta.(*cache)) + id, err := buildGroup(d, globalCache) if err != nil { return err } @@ -40,7 +40,7 @@ func resourceGroupRead(d *schema.ResourceData, meta interface{}) error { } func resourceGroupExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildGroup(d, meta.(*cache)) + id, err := buildGroup(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_networkd_unit.go b/builtin/providers/ignition/resource_ignition_networkd_unit.go index e5d822570..9fd40ed51 100644 --- a/builtin/providers/ignition/resource_ignition_networkd_unit.go +++ b/builtin/providers/ignition/resource_ignition_networkd_unit.go @@ -25,7 +25,7 @@ func resourceNetworkdUnit() *schema.Resource { } func resourceNetworkdUnitRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildNetworkdUnit(d, meta.(*cache)) + id, err := buildNetworkdUnit(d, globalCache) if err != nil { return err } @@ -40,7 +40,7 @@ func resourceNetworkdUnitDelete(d *schema.ResourceData, meta interface{}) error } func resourceNetworkdUnitExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildNetworkdUnit(d, meta.(*cache)) + id, err := buildNetworkdUnit(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_raid.go b/builtin/providers/ignition/resource_ignition_raid.go index 1c8b732ed..dab1a5f7c 100644 --- a/builtin/providers/ignition/resource_ignition_raid.go +++ b/builtin/providers/ignition/resource_ignition_raid.go @@ -36,7 +36,7 @@ func resourceRaid() *schema.Resource { } func resourceRaidRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildRaid(d, meta.(*cache)) + id, err := buildRaid(d, globalCache) if err != nil { return err } @@ -46,7 +46,7 @@ func resourceRaidRead(d *schema.ResourceData, meta interface{}) error { } func resourceRaidExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildRaid(d, meta.(*cache)) + id, err := buildRaid(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_systemd_unit.go b/builtin/providers/ignition/resource_ignition_systemd_unit.go index 211380024..88fe9b206 100644 --- a/builtin/providers/ignition/resource_ignition_systemd_unit.go +++ b/builtin/providers/ignition/resource_ignition_systemd_unit.go @@ -55,7 +55,7 @@ func resourceSystemdUnit() *schema.Resource { } func resourceSystemdUnitRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildSystemdUnit(d, meta.(*cache)) + id, err := buildSystemdUnit(d, globalCache) if err != nil { return err } @@ -65,7 +65,7 @@ func resourceSystemdUnitRead(d *schema.ResourceData, meta interface{}) error { } func resourceSystemdUnitExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildSystemdUnit(d, meta.(*cache)) + id, err := buildSystemdUnit(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/ignition/resource_ignition_user.go b/builtin/providers/ignition/resource_ignition_user.go index dd4ccc153..183e6c8c1 100644 --- a/builtin/providers/ignition/resource_ignition_user.go +++ b/builtin/providers/ignition/resource_ignition_user.go @@ -79,7 +79,7 @@ func resourceUser() *schema.Resource { } func resourceUserRead(d *schema.ResourceData, meta interface{}) error { - id, err := buildUser(d, meta.(*cache)) + id, err := buildUser(d, globalCache) if err != nil { return err } @@ -89,7 +89,7 @@ func resourceUserRead(d *schema.ResourceData, meta interface{}) error { } func resourceUserExists(d *schema.ResourceData, meta interface{}) (bool, error) { - id, err := buildUser(d, meta.(*cache)) + id, err := buildUser(d, globalCache) if err != nil { return false, err } diff --git a/builtin/providers/opc/resource_ip_address_association.go b/builtin/providers/opc/resource_ip_address_association.go index de7dec4db..59fcde858 100644 --- a/builtin/providers/opc/resource_ip_address_association.go +++ b/builtin/providers/opc/resource_ip_address_association.go @@ -82,7 +82,7 @@ func resourceOPCIPAddressAssociationRead(d *schema.ResourceData, meta interface{ name := d.Id() getInput := compute.GetIPAddressAssociationInput{ - name, + Name: name, } result, err := client.GetIPAddressAssociation(&getInput) if err != nil { diff --git a/builtin/providers/template/provider.go b/builtin/providers/template/provider.go index ece6c9f34..fb340754d 100644 --- a/builtin/providers/template/provider.go +++ b/builtin/providers/template/provider.go @@ -20,6 +20,7 @@ func Provider() terraform.ResourceProvider { "template_cloudinit_config", dataSourceCloudinitConfig(), ), + "template_dir": resourceDir(), }, } } diff --git a/builtin/providers/template/resource_template_dir.go b/builtin/providers/template/resource_template_dir.go new file mode 100644 index 000000000..63a2f18dc --- /dev/null +++ b/builtin/providers/template/resource_template_dir.go @@ -0,0 +1,234 @@ +package template + +import ( + "archive/tar" + "bytes" + "crypto/sha1" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "os" + "path" + "path/filepath" + + "github.com/hashicorp/terraform/helper/pathorcontents" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceDir() *schema.Resource { + return &schema.Resource{ + Create: resourceTemplateDirCreate, + Read: resourceTemplateDirRead, + Delete: resourceTemplateDirDelete, + + Schema: map[string]*schema.Schema{ + "source_dir": { + Type: schema.TypeString, + Description: "Path to the directory where the files to template reside", + Required: true, + ForceNew: true, + }, + "vars": { + Type: schema.TypeMap, + Optional: true, + Default: make(map[string]interface{}), + Description: "Variables to substitute", + ValidateFunc: validateVarsAttribute, + ForceNew: true, + }, + "destination_dir": { + Type: schema.TypeString, + Description: "Path to the directory where the templated files will be written", + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceTemplateDirRead(d *schema.ResourceData, meta interface{}) error { + sourceDir := d.Get("source_dir").(string) + destinationDir := d.Get("destination_dir").(string) + + // If the output doesn't exist, mark the resource for creation. + if _, err := os.Stat(destinationDir); os.IsNotExist(err) { + d.SetId("") + return nil + } + + // If the combined hash of the input and output directories is different from + // the stored one, mark the resource for re-creation. + // + // The output directory is technically enough for the general case, but by + // hashing the input directory as well, we make development much easier: when + // a developer modifies one of the input files, the generation is + // re-triggered. + hash, err := generateID(sourceDir, destinationDir) + if err != nil { + return err + } + if hash != d.Id() { + d.SetId("") + return nil + } + + return nil +} + +func resourceTemplateDirCreate(d *schema.ResourceData, meta interface{}) error { + sourceDir := d.Get("source_dir").(string) + destinationDir := d.Get("destination_dir").(string) + vars := d.Get("vars").(map[string]interface{}) + + // Always delete the output first, otherwise files that got deleted from the + // input directory might still be present in the output afterwards. + if err := resourceTemplateDirDelete(d, meta); err != nil { + return err + } + + // Create the destination directory and any other intermediate directories + // leading to it. + if _, err := os.Stat(destinationDir); err != nil { + if err := os.MkdirAll(destinationDir, 0777); err != nil { + return err + } + } + + // Recursively crawl the input files/directories and generate the output ones. + err := filepath.Walk(sourceDir, func(p string, f os.FileInfo, err error) error { + if err != nil { + return err + } + + if f.IsDir() { + return nil + } + + relPath, _ := filepath.Rel(sourceDir, p) + return generateDirFile(p, path.Join(destinationDir, relPath), f, vars) + }) + if err != nil { + return err + } + + // Compute ID. + hash, err := generateID(sourceDir, destinationDir) + if err != nil { + return err + } + d.SetId(hash) + + return nil +} + +func resourceTemplateDirDelete(d *schema.ResourceData, _ interface{}) error { + d.SetId("") + + destinationDir := d.Get("destination_dir").(string) + if _, err := os.Stat(destinationDir); os.IsNotExist(err) { + return nil + } + + if err := os.RemoveAll(destinationDir); err != nil { + return fmt.Errorf("could not delete directory %q: %s", destinationDir, err) + } + + return nil +} + +func generateDirFile(sourceDir, destinationDir string, f os.FileInfo, vars map[string]interface{}) error { + inputContent, _, err := pathorcontents.Read(sourceDir) + if err != nil { + return err + } + + outputContent, err := execute(inputContent, vars) + if err != nil { + return templateRenderError(fmt.Errorf("failed to render %v: %v", sourceDir, err)) + } + + outputDir := path.Dir(destinationDir) + if _, err := os.Stat(outputDir); err != nil { + if err := os.MkdirAll(outputDir, 0777); err != nil { + return err + } + } + + err = ioutil.WriteFile(destinationDir, []byte(outputContent), f.Mode()) + if err != nil { + return err + } + + return nil +} + +func generateID(sourceDir, destinationDir string) (string, error) { + inputHash, err := generateDirHash(sourceDir) + if err != nil { + return "", err + } + outputHash, err := generateDirHash(destinationDir) + if err != nil { + return "", err + } + checksum := sha1.Sum([]byte(inputHash + outputHash)) + return hex.EncodeToString(checksum[:]), nil +} + +func generateDirHash(directoryPath string) (string, error) { + tarData, err := tarDir(directoryPath) + if err != nil { + return "", fmt.Errorf("could not generate output checksum: %s", err) + } + + checksum := sha1.Sum(tarData) + return hex.EncodeToString(checksum[:]), nil +} + +func tarDir(directoryPath string) ([]byte, error) { + buf := new(bytes.Buffer) + tw := tar.NewWriter(buf) + + writeFile := func(p string, f os.FileInfo, err error) error { + if err != nil { + return err + } + + var header *tar.Header + var file *os.File + + header, err = tar.FileInfoHeader(f, f.Name()) + if err != nil { + return err + } + relPath, _ := filepath.Rel(directoryPath, p) + header.Name = relPath + + if err := tw.WriteHeader(header); err != nil { + return err + } + + if f.IsDir() { + return nil + } + + file, err = os.Open(p) + if err != nil { + return err + } + defer file.Close() + + _, err = io.Copy(tw, file) + return err + } + + if err := filepath.Walk(directoryPath, writeFile); err != nil { + return []byte{}, err + } + if err := tw.Flush(); err != nil { + return []byte{}, err + } + + return buf.Bytes(), nil +} diff --git a/builtin/providers/template/resource_template_dir_test.go b/builtin/providers/template/resource_template_dir_test.go new file mode 100644 index 000000000..716a5f0af --- /dev/null +++ b/builtin/providers/template/resource_template_dir_test.go @@ -0,0 +1,104 @@ +package template + +import ( + "fmt" + "testing" + + "errors" + r "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "io/ioutil" + "os" + "path/filepath" +) + +const templateDirRenderingConfig = ` +resource "template_dir" "dir" { + source_dir = "%s" + destination_dir = "%s" + vars = %s +}` + +type testTemplate struct { + template string + want string +} + +func testTemplateDirWriteFiles(files map[string]testTemplate) (in, out string, err error) { + in, err = ioutil.TempDir(os.TempDir(), "terraform_template_dir") + if err != nil { + return + } + + for name, file := range files { + path := filepath.Join(in, name) + + err = os.MkdirAll(filepath.Dir(path), 0777) + if err != nil { + return + } + + err = ioutil.WriteFile(path, []byte(file.template), 0777) + if err != nil { + return + } + } + + out = fmt.Sprintf("%s.out", in) + return +} + +func TestTemplateDirRendering(t *testing.T) { + var cases = []struct { + vars string + files map[string]testTemplate + }{ + { + files: map[string]testTemplate{ + "foo.txt": {"${bar}", "bar"}, + "nested/monkey.txt": {"ooh-ooh-ooh-eee-eee", "ooh-ooh-ooh-eee-eee"}, + "maths.txt": {"${1+2+3}", "6"}, + }, + vars: `{bar = "bar"}`, + }, + } + + for _, tt := range cases { + // Write the desired templates in a temporary directory. + in, out, err := testTemplateDirWriteFiles(tt.files) + if err != nil { + t.Skipf("could not write templates to temporary directory: %s", err) + continue + } + defer os.RemoveAll(in) + defer os.RemoveAll(out) + + // Run test case. + r.UnitTest(t, r.TestCase{ + Providers: testProviders, + Steps: []r.TestStep{ + { + Config: fmt.Sprintf(templateDirRenderingConfig, in, out, tt.vars), + Check: func(s *terraform.State) error { + for name, file := range tt.files { + content, err := ioutil.ReadFile(filepath.Join(out, name)) + if err != nil { + return fmt.Errorf("template:\n%s\nvars:\n%s\ngot:\n%s\nwant:\n%s\n", file.template, tt.vars, err, file.want) + } + if string(content) != file.want { + return fmt.Errorf("template:\n%s\nvars:\n%s\ngot:\n%s\nwant:\n%s\n", file.template, tt.vars, content, file.want) + } + } + return nil + }, + }, + }, + CheckDestroy: func(*terraform.State) error { + if _, err := os.Stat(out); os.IsNotExist(err) { + return nil + } + return errors.New("template_dir did not get destroyed") + }, + }) + } +} diff --git a/builtin/providers/triton/provider.go b/builtin/providers/triton/provider.go index 31e3659e9..4c21722c2 100644 --- a/builtin/providers/triton/provider.go +++ b/builtin/providers/triton/provider.go @@ -22,25 +22,25 @@ func Provider() terraform.ResourceProvider { "account": { Type: schema.TypeString, Required: true, - DefaultFunc: schema.EnvDefaultFunc("SDC_ACCOUNT", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_ACCOUNT", "SDC_ACCOUNT"}, ""), }, "url": { Type: schema.TypeString, Required: true, - DefaultFunc: schema.EnvDefaultFunc("SDC_URL", "https://us-west-1.api.joyentcloud.com"), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_URL", "SDC_URL"}, "https://us-west-1.api.joyentcloud.com"), }, "key_material": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("SDC_KEY_MATERIAL", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_KEY_MATERIAL", "SDC_KEY_MATERIAL"}, ""), }, "key_id": { Type: schema.TypeString, Required: true, - DefaultFunc: schema.EnvDefaultFunc("SDC_KEY_ID", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_KEY_ID", "SDC_KEY_ID"}, ""), }, }, diff --git a/builtin/providers/ultradns/resource_ultradns_rdpool.go b/builtin/providers/ultradns/resource_ultradns_rdpool.go index a45ff6939..5f8bbff6c 100644 --- a/builtin/providers/ultradns/resource_ultradns_rdpool.go +++ b/builtin/providers/ultradns/resource_ultradns_rdpool.go @@ -7,6 +7,7 @@ import ( "github.com/Ensighten/udnssdk" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" ) func resourceUltradnsRdpool() *schema.Resource { @@ -28,12 +29,6 @@ func resourceUltradnsRdpool() *schema.Resource { Required: true, ForceNew: true, }, - "order": &schema.Schema{ - Type: schema.TypeString, - Required: true, - // 0-255 char - // FIXED | RANDOM | ROUND_ROBIN - }, "rdata": &schema.Schema{ Type: schema.TypeSet, Set: schema.HashString, @@ -41,10 +36,20 @@ func resourceUltradnsRdpool() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, // Optional - "description": &schema.Schema{ + "order": &schema.Schema{ Type: schema.TypeString, Optional: true, - // 0-255 char + Default: "ROUND_ROBIN", + ValidateFunc: validation.StringInSlice([]string{ + "ROUND_ROBIN", + "FIXED", + "RANDOM", + }, false), + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 255), }, "ttl": &schema.Schema{ Type: schema.TypeInt, @@ -111,8 +116,7 @@ func resourceUltradnsRdpoolRead(d *schema.ResourceData, meta interface{}) error r := rrsets[0] zone := d.Get("zone") - // ttl - d.Set("ttl", r.TTL) + // hostname if r.OwnerName == "" { d.Set("hostname", zone) @@ -134,11 +138,11 @@ func resourceUltradnsRdpoolRead(d *schema.ResourceData, meta interface{}) error } // Set simple values + d.Set("ttl", r.TTL) d.Set("description", p.Description) d.Set("order", p.Order) err = d.Set("rdata", makeSetFromStrings(r.RData)) - //err = d.Set("rdata", makeSetFromRdataAlone(r.RData)) if err != nil { return fmt.Errorf("rdata set failed: %#v", err) } @@ -186,13 +190,12 @@ func resourceUltradnsRdpoolDelete(d *schema.ResourceData, meta interface{}) erro func newRRSetResourceFromRdpool(d *schema.ResourceData) (rRSetResource, error) { //rDataRaw := d.Get("rdata").(*schema.Set).List() r := rRSetResource{ - // "The only valid rrtype value for SiteBacker or Traffic Controller pools is A" + // "The only valid rrtype value for RDpools is A" // per https://portal.ultradns.com/static/docs/REST-API_User_Guide.pdf RRType: "A", Zone: d.Get("zone").(string), OwnerName: d.Get("name").(string), TTL: d.Get("ttl").(int), - //RData: unzipRdataHosts(rDataRaw), } if attr, ok := d.GetOk("rdata"); ok { rdata := attr.(*schema.Set).List() @@ -213,27 +216,3 @@ func newRRSetResourceFromRdpool(d *schema.ResourceData) (rRSetResource, error) { return r, nil } - -// zip RData into []map[string]interface{} -func zipRDataAlone(rds []string) []map[string]interface{} { - result := make([]map[string]interface{}, 0, len(rds)) - for _, rd := range rds { - r := map[string]interface{}{ - // "host": rds[i], - "host": rd, - } - result = append(result, r) - } - return result -} - -// makeSetFromRdatas encodes an array of Rdata into a -// *schema.Set in the appropriate structure for the schema -func makeSetFromRdataAlone(rds []string) *schema.Set { - s := &schema.Set{F: hashRdatas} - rs := zipRDataAlone(rds) - for _, r := range rs { - s.Add(r) - } - return s -} diff --git a/command/apply.go b/command/apply.go index ca9813eb5..1e49739a0 100644 --- a/command/apply.go +++ b/command/apply.go @@ -201,7 +201,7 @@ func (c *ApplyCommand) Run(args []string) int { ctxCancel() // Notify the user - c.Ui.Output("Interrupt received. Gracefully shutting down...") + c.Ui.Output(outputInterrupt) // Still get the result, since there is still one select { @@ -418,3 +418,7 @@ func outputsAsString(state *terraform.State, modPath []string, schema []*config. return strings.TrimSpace(outputBuf.String()) } + +const outputInterrupt = `Interrupt received. +Please wait for Terraform to exit or data loss may occur. +Gracefully shutting down...` diff --git a/command/apply_test.go b/command/apply_test.go index abc33dae5..5700ade69 100644 --- a/command/apply_test.go +++ b/command/apply_test.go @@ -841,7 +841,7 @@ func TestApply_planVars(t *testing.T) { // we should be able to apply a plan file with no other file dependencies func TestApply_planNoModuleFiles(t *testing.T) { - // temprary data directory which we can remove between commands + // temporary data directory which we can remove between commands td, err := ioutil.TempDir("", "tf") if err != nil { t.Fatal(err) diff --git a/command/init.go b/command/init.go index 54a244cdd..ff0aadc9d 100644 --- a/command/init.go +++ b/command/init.go @@ -194,7 +194,7 @@ Usage: terraform init [options] [SOURCE] [PATH] This is the first command that should be run for any new or existing Terraform configuration per machine. This sets up all the local data - necessary to run Terraform that is typically not comitted to version + necessary to run Terraform that is typically not committed to version control. This command is always safe to run multiple times. Though subsequent runs diff --git a/command/internal_plugin_list.go b/command/internal_plugin_list.go index 0092d8f88..1b3302f0a 100644 --- a/command/internal_plugin_list.go +++ b/command/internal_plugin_list.go @@ -31,6 +31,7 @@ import ( externalprovider "github.com/hashicorp/terraform/builtin/providers/external" fastlyprovider "github.com/hashicorp/terraform/builtin/providers/fastly" githubprovider "github.com/hashicorp/terraform/builtin/providers/github" + gitlabprovider "github.com/hashicorp/terraform/builtin/providers/gitlab" googleprovider "github.com/hashicorp/terraform/builtin/providers/google" grafanaprovider "github.com/hashicorp/terraform/builtin/providers/grafana" herokuprovider "github.com/hashicorp/terraform/builtin/providers/heroku" @@ -110,6 +111,7 @@ var InternalProviders = map[string]plugin.ProviderFunc{ "external": externalprovider.Provider, "fastly": fastlyprovider.Provider, "github": githubprovider.Provider, + "gitlab": gitlabprovider.Provider, "google": googleprovider.Provider, "grafana": grafanaprovider.Provider, "heroku": herokuprovider.Provider, diff --git a/command/meta_backend.go b/command/meta_backend.go index 6f75acc77..f1e886e34 100644 --- a/command/meta_backend.go +++ b/command/meta_backend.go @@ -1200,7 +1200,7 @@ func (m *Meta) backend_C_r_S_unchanged( s := sMgr.State() // it's possible for a backend to be unchanged, and the config itself to - // have changed by moving a paramter from the config to `-backend-config` + // have changed by moving a parameter from the config to `-backend-config` // In this case we only need to update the Hash. if c != nil && s.Backend.Hash != c.Hash { s.Backend.Hash = c.Hash diff --git a/command/state_mv.go b/command/state_mv.go index 7982d7b92..5b99dd2ab 100644 --- a/command/state_mv.go +++ b/command/state_mv.go @@ -133,7 +133,7 @@ func (c *StateMvCommand) Run(args []string) int { } // addableResult takes the result from a filter operation and returns what to -// call State.Add with. The reason we do this is beacuse in the module case +// call State.Add with. The reason we do this is because in the module case // we must add the list of all modules returned versus just the root module. func (c *StateMvCommand) addableResult(results []*terraform.StateFilterResult) interface{} { switch v := results[0].Value.(type) { diff --git a/dag/walk.go b/dag/walk.go index a74f1142a..23c87adc1 100644 --- a/dag/walk.go +++ b/dag/walk.go @@ -352,7 +352,7 @@ func (w *Walker) walkVertex(v Vertex, info *walkerVertex) { } // Check if we have updated dependencies. This can happen if the - // dependencies were satisfied exactly prior to an Update occuring. + // dependencies were satisfied exactly prior to an Update occurring. // In that case, we'd like to take into account new dependencies // if possible. info.DepsLock.Lock() diff --git a/examples/digitalocean/variable.tf b/examples/digitalocean/variable.tf index 179b8d803..2068806a4 100644 --- a/examples/digitalocean/variable.tf +++ b/examples/digitalocean/variable.tf @@ -1,6 +1,6 @@ # #### -# Current Availiable Datacenter Regions +# Current Available Datacenter Regions # As of 05-07-2016 diff --git a/examples/gce-vpn/vpn.tf b/examples/gce-vpn/vpn.tf index d9f86cbc7..a588fd53d 100644 --- a/examples/gce-vpn/vpn.tf +++ b/examples/gce-vpn/vpn.tf @@ -5,7 +5,7 @@ provider "google" { region = "${var.region1}" } -# Create the two networks we want to join. They must have seperate, internal +# Create the two networks we want to join. They must have separate, internal # ranges. resource "google_compute_network" "network1" { name = "network1" diff --git a/flatmap/expand.go b/flatmap/expand.go index 2bfb3fe3d..e0b81b641 100644 --- a/flatmap/expand.go +++ b/flatmap/expand.go @@ -115,7 +115,7 @@ func expandArray(m map[string]string, prefix string) []interface{} { func expandMap(m map[string]string, prefix string) map[string]interface{} { // Submaps may not have a '%' key, so we can't count on this value being - // here. If we don't have a count, just procede as if we have have a map. + // here. If we don't have a count, just proceed as if we have have a map. if count, ok := m[prefix+"%"]; ok && count == "0" { return map[string]interface{}{} } diff --git a/terraform/version.go b/terraform/version.go index 5dbc57fce..22e68c9ee 100644 --- a/terraform/version.go +++ b/terraform/version.go @@ -7,7 +7,7 @@ import ( ) // The main version number that is being run at the moment. -const Version = "0.9.4" +const Version = "0.9.5" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff --git a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md index 257bf0a68..25f7feb2f 100644 --- a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md @@ -1,3 +1,66 @@ +Release v1.8.16 (2017-04-21) +=== + +### Service Client Updates +* `service/appstream`: Updates service API, documentation, and paginators + * The new feature named "Default Internet Access" will enable Internet access from AppStream 2.0 instances - image builders and fleet instances. Admins will check a flag either through AWS management console for AppStream 2.0 or through API while creating an image builder or while creating/updating a fleet. +* `service/kinesis`: Updates service API, documentation, waiters, and paginators + * Adds a new waiter, StreamNotExists, to Kinesis. + +### SDK Enhancements +* `aws/endpoints`: Add utilities improving endpoints lookup (#1218) + * Adds several utilities to the endpoints packages to make looking up partitions, regions, and services easier. + * Fixes #994 + +### SDK Bugs +* `private/protocol/xml/xmlutil`: Fix unmarshaling dropping errors (#1219) + * The XML unmarshaler would drop any serialization or body read error that occurred on the floor effectively hiding any errors that would occur. + * Fixes #1205 +Release v1.8.15 (2017-04-20) +=== + +### Service Client Updates +* `service/devicefarm`: Updates service API and documentation + * API Update for AWS Device Farm: Support for Deals and Promotions +* `service/directconnect`: Updates service documentation + * Documentation updates for AWS Direct Connect. +* `service/elbv2`: Updates service waiters +* `service/kms`: Updates service documentation and examples + * Doc-only update for Key Management Service (KMS): Update docs for GrantConstraints and GenerateRandom +* `service/route53`: Updates service documentation + * Release notes: SDK documentation now includes examples for ChangeResourceRecordSets for all types of resource record set, such as weighted, alias, and failover. +* `service/route53domains`: Updates service API, documentation, and paginators + * Adding examples and other documentation updates. + +### SDK Enhancements +* `service/s3`: Add utilities to make getting a bucket's region easier (#1207) + * Adds two features which make it easier to get a bucket's region, `s3.NormalizeBucketLocation` and `s3manager.GetBucketRegion`. + +### SDK Bugs +* `service/s3`: Fix HeadObject's incorrect documented error codes (#1213) + * The HeadObject's model incorrectly states that the operation can return the NoSuchKey error code. + * Fixes #1208 + +Release v1.8.14 (2017-04-19) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * Add support for "embed" property. +* `service/codestar`: Adds new service + * AWS CodeStar is a cloud-based service for creating, managing, and working with software development projects on AWS. An AWS CodeStar project creates and integrates AWS services for your project development toolchain. AWS CodeStar also manages the permissions required for project users. +* `service/ec2`: Updates service API and documentation + * Adds support for creating an Amazon FPGA Image (AFI) from a specified design checkpoint (DCP). +* `service/iam`: Updates service API and documentation + * This changes introduces a new IAM role type, Service Linked Role, which works like a normal role but must be managed via services' control. +* `service/lambda`: Updates service API and documentation + * Lambda integration with CloudDebugger service to enable customers to enable tracing for the Lambda functions and send trace information to the CloudDebugger service. +* `service/lexmodelbuildingservice`: Adds new service +* `service/polly`: Updates service API, documentation, and paginators + * API Update for Amazon Polly: Add support for speech marks +* `service/rekognition`: Updates service API and documentation + * Given an image, the API detects explicit or suggestive adult content in the image and returns a list of corresponding labels with confidence scores, as well as a taxonomy (parent-child relation) for each label. + Release v1.8.13 (2017-04-18) === diff --git a/vendor/github.com/aws/aws-sdk-go/Makefile b/vendor/github.com/aws/aws-sdk-go/Makefile index fc2bc0cef..b1611d2e3 100644 --- a/vendor/github.com/aws/aws-sdk-go/Makefile +++ b/vendor/github.com/aws/aws-sdk-go/Makefile @@ -64,6 +64,9 @@ integration: get-deps-tests integ-custom smoke-tests performance integ-custom: go test -tags "integration" ./awstesting/integration/customizations/... +cleanup-integ: + go run -tags "integration" ./awstesting/cmd/bucket_cleanup/main.go "aws-sdk-go-integration" + smoke-tests: get-deps-tests gucumber -go-tags "integration" ./awstesting/integration/smoke diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go index b2428c286..48b0fbd93 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go @@ -5,6 +5,7 @@ import ( "net/http/httputil" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/client/metadata" "github.com/aws/aws-sdk-go/aws/request" ) @@ -105,6 +106,7 @@ func logRequest(r *request.Request) { dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) if err != nil { r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + r.Error = awserr.New(request.ErrCodeRead, "an error occurred during request body reading", err) return } @@ -135,6 +137,7 @@ func logResponse(r *request.Request) { dumpedBody, err := httputil.DumpResponse(r.HTTPResponse, logBody) if err != nil { r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + r.Error = awserr.New(request.ErrCodeRead, "an error occurred during response body reading", err) return } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go index 43a3676b7..1313478f2 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go @@ -54,6 +54,12 @@ func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { // ShouldRetry returns true if the request should be retried. func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable != nil { + return *r.Retryable + } + if r.HTTPResponse.StatusCode >= 500 { return true } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go index 948e0a679..d1f31f1c6 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -53,6 +53,13 @@ type Config struct { // to use based on region. EndpointResolver endpoints.Resolver + // EnforceShouldRetryCheck is used in the AfterRetryHandler to always call + // ShouldRetry regardless of whether or not if request.Retryable is set. + // This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck + // is not set, then ShouldRetry will only be called if request.Retryable is nil. + // Proper handling of the request.Retryable field is important when setting this field. + EnforceShouldRetryCheck *bool + // The region to send requests to. This parameter is required and must // be configured globally or on a per-client basis unless otherwise // noted. A full list of regions is found in the "Regions and Endpoints" @@ -443,6 +450,10 @@ func mergeInConfig(dst *Config, other *Config) { if other.DisableRestProtocolURICleaning != nil { dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning } + + if other.EnforceShouldRetryCheck != nil { + dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck + } } // Copy will return a shallow copy of the Config object. If any additional diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go index 08a666590..25b461c31 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go @@ -27,7 +27,7 @@ type lener interface { // or will use the HTTPRequest.Header's "Content-Length" if defined. If unable // to determine request body length and no "Content-Length" was specified it will panic. // -// The Content-Length will only be aded to the request if the length of the body +// The Content-Length will only be added to the request if the length of the body // is greater than 0. If the body is empty or the current `Content-Length` // header is <= 0, the header will also be stripped. var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) { @@ -71,8 +71,8 @@ var reStatusCode = regexp.MustCompile(`^(\d{3})`) // ValidateReqSigHandler is a request handler to ensure that the request's // signature doesn't expire before it is sent. This can happen when a request -// is built and signed signficantly before it is sent. Or significant delays -// occur whne retrying requests that would cause the signature to expire. +// is built and signed significantly before it is sent. Or significant delays +// occur when retrying requests that would cause the signature to expire. var ValidateReqSigHandler = request.NamedHandler{ Name: "core.ValidateReqSigHandler", Fn: func(r *request.Request) { @@ -98,54 +98,79 @@ var ValidateReqSigHandler = request.NamedHandler{ } // SendHandler is a request handler to send service request using HTTP client. -var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) { - var err error - r.HTTPResponse, err = r.Config.HTTPClient.Do(r.HTTPRequest) - if err != nil { - // Prevent leaking if an HTTPResponse was returned. Clean up - // the body. - if r.HTTPResponse != nil { - r.HTTPResponse.Body.Close() +var SendHandler = request.NamedHandler{ + Name: "core.SendHandler", + Fn: func(r *request.Request) { + sender := sendFollowRedirects + if r.DisableFollowRedirects { + sender = sendWithoutFollowRedirects } - // Capture the case where url.Error is returned for error processing - // response. e.g. 301 without location header comes back as string - // error and r.HTTPResponse is nil. Other url redirect errors will - // comeback in a similar method. - if e, ok := err.(*url.Error); ok && e.Err != nil { - if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { - code, _ := strconv.ParseInt(s[1], 10, 64) - r.HTTPResponse = &http.Response{ - StatusCode: int(code), - Status: http.StatusText(int(code)), - Body: ioutil.NopCloser(bytes.NewReader([]byte{})), - } - return - } + + var err error + r.HTTPResponse, err = sender(r) + if err != nil { + handleSendError(r, err) } - if r.HTTPResponse == nil { - // Add a dummy request response object to ensure the HTTPResponse - // value is consistent. + }, +} + +func sendFollowRedirects(r *request.Request) (*http.Response, error) { + return r.Config.HTTPClient.Do(r.HTTPRequest) +} + +func sendWithoutFollowRedirects(r *request.Request) (*http.Response, error) { + transport := r.Config.HTTPClient.Transport + if transport == nil { + transport = http.DefaultTransport + } + + return transport.RoundTrip(r.HTTPRequest) +} + +func handleSendError(r *request.Request, err error) { + // Prevent leaking if an HTTPResponse was returned. Clean up + // the body. + if r.HTTPResponse != nil { + r.HTTPResponse.Body.Close() + } + // Capture the case where url.Error is returned for error processing + // response. e.g. 301 without location header comes back as string + // error and r.HTTPResponse is nil. Other URL redirect errors will + // comeback in a similar method. + if e, ok := err.(*url.Error); ok && e.Err != nil { + if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { + code, _ := strconv.ParseInt(s[1], 10, 64) r.HTTPResponse = &http.Response{ - StatusCode: int(0), - Status: http.StatusText(int(0)), + StatusCode: int(code), + Status: http.StatusText(int(code)), Body: ioutil.NopCloser(bytes.NewReader([]byte{})), } - } - // Catch all other request errors. - r.Error = awserr.New("RequestError", "send request failed", err) - r.Retryable = aws.Bool(true) // network errors are retryable - - // Override the error with a context canceled error, if that was canceled. - ctx := r.Context() - select { - case <-ctx.Done(): - r.Error = awserr.New(request.CanceledErrorCode, - "request context canceled", ctx.Err()) - r.Retryable = aws.Bool(false) - default: + return } } -}} + if r.HTTPResponse == nil { + // Add a dummy request response object to ensure the HTTPResponse + // value is consistent. + r.HTTPResponse = &http.Response{ + StatusCode: int(0), + Status: http.StatusText(int(0)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + } + // Catch all other request errors. + r.Error = awserr.New("RequestError", "send request failed", err) + r.Retryable = aws.Bool(true) // network errors are retryable + + // Override the error with a context canceled error, if that was canceled. + ctx := r.Context() + select { + case <-ctx.Done(): + r.Error = awserr.New(request.CanceledErrorCode, + "request context canceled", ctx.Err()) + r.Retryable = aws.Bool(false) + default: + } +} // ValidateResponseHandler is a request handler to validate service response. var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) { @@ -160,7 +185,7 @@ var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseH var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) { // If one of the other handlers already set the retry state // we don't want to override it based on the service's state - if r.Retryable == nil { + if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) { r.Retryable = aws.Bool(r.ShouldRetry(r)) } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index 4adca3a7f..73c0afc1f 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -142,17 +142,20 @@ const ( // DefaultResolver returns an Endpoint resolver that will be able // to resolve endpoints for: AWS Standard, AWS China, and AWS GovCloud (US). // -// Casting the return value of this func to a EnumPartitions will -// allow you to get a list of the partitions in the order the endpoints -// will be resolved in. +// Use DefaultPartitions() to get the list of the default partitions. +func DefaultResolver() Resolver { + return defaultPartitions +} + +// DefaultPartitions returns a list of the partitions the SDK is bundled +// with. The available partitions are: AWS Standard, AWS China, and AWS GovCloud (US). // -// resolver := endpoints.DefaultResolver() -// partitions := resolver.(endpoints.EnumPartitions).Partitions() +// partitions := endpoints.DefaultPartitions // for _, p := range partitions { // // ... inspect partitions // } -func DefaultResolver() Resolver { - return defaultPartitions +func DefaultPartitions() []Partition { + return defaultPartitions.Partitions() } var defaultPartitions = partitions{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go index 37e19ab00..64dccea43 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go @@ -124,6 +124,49 @@ type EnumPartitions interface { Partitions() []Partition } +// RegionsForService returns a map of regions for the partition and service. +// If either the partition or service does not exist false will be returned +// as the second parameter. +// +// This example shows how to get the regions for DynamoDB in the AWS partition. +// rs := RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamoDBServiceID) +// +// This is equivalent to using the partition directly. +// rs := endpoints.AwsPartition().Services()[endpoints.DynamoDBServiceID].Regions() +func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) { + for _, p := range ps { + if p.ID() != partitionID { + continue + } + if _, ok := p.p.Services[serviceID]; !ok { + break + } + + s := Service{ + id: serviceID, + p: p.p, + } + return s.Regions(), true + } + + return map[string]Region{}, false +} + +// PartitionForRegion returns the first partition which includes the region +// passed in. This includes both known regions and regions which match +// a pattern supported by the partition which may include regions that are +// not explicitly known by the partition. Use the Regions method of the +// returned Partition if explicit support is needed. +func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) { + for _, p := range ps { + if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) { + return p, true + } + } + + return Partition{}, false +} + // A Partition provides the ability to enumerate the partition's regions // and services. type Partition struct { @@ -132,7 +175,7 @@ type Partition struct { } // ID returns the identifier of the partition. -func (p *Partition) ID() string { return p.id } +func (p Partition) ID() string { return p.id } // EndpointFor attempts to resolve the endpoint based on service and region. // See Options for information on configuring how the endpoint is resolved. @@ -155,13 +198,13 @@ func (p *Partition) ID() string { return p.id } // Errors that can be returned. // * UnknownServiceError // * UnknownEndpointError -func (p *Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { +func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { return p.p.EndpointFor(service, region, opts...) } // Regions returns a map of Regions indexed by their ID. This is useful for // enumerating over the regions in a partition. -func (p *Partition) Regions() map[string]Region { +func (p Partition) Regions() map[string]Region { rs := map[string]Region{} for id := range p.p.Regions { rs[id] = Region{ @@ -175,7 +218,7 @@ func (p *Partition) Regions() map[string]Region { // Services returns a map of Service indexed by their ID. This is useful for // enumerating over the services in a partition. -func (p *Partition) Services() map[string]Service { +func (p Partition) Services() map[string]Service { ss := map[string]Service{} for id := range p.p.Services { ss[id] = Service{ @@ -195,16 +238,16 @@ type Region struct { } // ID returns the region's identifier. -func (r *Region) ID() string { return r.id } +func (r Region) ID() string { return r.id } // ResolveEndpoint resolves an endpoint from the context of the region given // a service. See Partition.EndpointFor for usage and errors that can be returned. -func (r *Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) { +func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) { return r.p.EndpointFor(service, r.id, opts...) } // Services returns a list of all services that are known to be in this region. -func (r *Region) Services() map[string]Service { +func (r Region) Services() map[string]Service { ss := map[string]Service{} for id, s := range r.p.Services { if _, ok := s.Endpoints[r.id]; ok { @@ -226,17 +269,38 @@ type Service struct { } // ID returns the identifier for the service. -func (s *Service) ID() string { return s.id } +func (s Service) ID() string { return s.id } // ResolveEndpoint resolves an endpoint from the context of a service given // a region. See Partition.EndpointFor for usage and errors that can be returned. -func (s *Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) { +func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) { return s.p.EndpointFor(s.id, region, opts...) } +// Regions returns a map of Regions that the service is present in. +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Regions() map[string]Region { + rs := map[string]Region{} + for id := range s.p.Services[s.id].Endpoints { + if _, ok := s.p.Regions[id]; ok { + rs[id] = Region{ + id: id, + p: s.p, + } + } + } + + return rs +} + // Endpoints returns a map of Endpoints indexed by their ID for all known // endpoints for a service. -func (s *Service) Endpoints() map[string]Endpoint { +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Endpoints() map[string]Endpoint { es := map[string]Endpoint{} for id := range s.p.Services[s.id].Endpoints { es[id] = Endpoint{ @@ -259,15 +323,15 @@ type Endpoint struct { } // ID returns the identifier for an endpoint. -func (e *Endpoint) ID() string { return e.id } +func (e Endpoint) ID() string { return e.id } // ServiceID returns the identifier the endpoint belongs to. -func (e *Endpoint) ServiceID() string { return e.serviceID } +func (e Endpoint) ServiceID() string { return e.serviceID } // ResolveEndpoint resolves an endpoint from the context of a service and // region the endpoint represents. See Partition.EndpointFor for usage and // errors that can be returned. -func (e *Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) { +func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) { return e.p.EndpointFor(e.serviceID, e.id, opts...) } @@ -300,28 +364,6 @@ type EndpointNotFoundError struct { Region string } -//// NewEndpointNotFoundError builds and returns NewEndpointNotFoundError. -//func NewEndpointNotFoundError(p, s, r string) EndpointNotFoundError { -// return EndpointNotFoundError{ -// awsError: awserr.New("EndpointNotFoundError", "unable to find endpoint", nil), -// Partition: p, -// Service: s, -// Region: r, -// } -//} -// -//// Error returns string representation of the error. -//func (e EndpointNotFoundError) Error() string { -// extra := fmt.Sprintf("partition: %q, service: %q, region: %q", -// e.Partition, e.Service, e.Region) -// return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr()) -//} -// -//// String returns the string representation of the error. -//func (e EndpointNotFoundError) String() string { -// return e.Error() -//} - // A UnknownServiceError is returned when the service does not resolve to an // endpoint. Includes a list of all known services for the partition. Returned // when a partition does not support the service. diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go index fc7eada77..05e92df22 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go @@ -209,17 +209,20 @@ import ( // DefaultResolver returns an Endpoint resolver that will be able // to resolve endpoints for: {{ ListPartitionNames . }}. // - // Casting the return value of this func to a EnumPartitions will - // allow you to get a list of the partitions in the order the endpoints - // will be resolved in. + // Use DefaultPartitions() to get the list of the default partitions. + func DefaultResolver() Resolver { + return defaultPartitions + } + + // DefaultPartitions returns a list of the partitions the SDK is bundled + // with. The available partitions are: {{ ListPartitionNames . }}. // - // resolver := endpoints.DefaultResolver() - // partitions := resolver.(endpoints.EnumPartitions).Partitions() + // partitions := endpoints.DefaultPartitions // for _, p := range partitions { // // ... inspect partitions // } - func DefaultResolver() Resolver { - return defaultPartitions + func DefaultPartitions() []Partition { + return defaultPartitions.Partitions() } var defaultPartitions = partitions{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/serialization_error.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go similarity index 100% rename from vendor/github.com/aws/aws-sdk-go/aws/request/serialization_error.go rename to vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go index 1f131dfd3..4f4f1123a 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -21,6 +21,9 @@ const ( // during protocol unmarshaling. ErrCodeSerialization = "SerializationError" + // ErrCodeRead is an error that is returned during HTTP reads. + ErrCodeRead = "ReadError" + // ErrCodeResponseTimeout is the connection timeout error that is recieved // during body reads. ErrCodeResponseTimeout = "ResponseTimeout" @@ -38,23 +41,24 @@ type Request struct { Handlers Handlers Retryer - Time time.Time - ExpireTime time.Duration - Operation *Operation - HTTPRequest *http.Request - HTTPResponse *http.Response - Body io.ReadSeeker - BodyStart int64 // offset from beginning of Body that the request body starts - Params interface{} - Error error - Data interface{} - RequestID string - RetryCount int - Retryable *bool - RetryDelay time.Duration - NotHoist bool - SignedHeaderVals http.Header - LastSignedAt time.Time + Time time.Time + ExpireTime time.Duration + Operation *Operation + HTTPRequest *http.Request + HTTPResponse *http.Response + Body io.ReadSeeker + BodyStart int64 // offset from beginning of Body that the request body starts + Params interface{} + Error error + Data interface{} + RequestID string + RetryCount int + Retryable *bool + RetryDelay time.Duration + NotHoist bool + SignedHeaderVals http.Header + LastSignedAt time.Time + DisableFollowRedirects bool context aws.Context diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go index bf07a1e9c..7af81de2a 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go @@ -70,7 +70,21 @@ func isCodeExpiredCreds(code string) bool { return ok } -func isSerializationErrorRetryable(err error) bool { +var validParentCodes = map[string]struct{}{ + ErrCodeSerialization: struct{}{}, + ErrCodeRead: struct{}{}, +} + +func isNestedErrorRetryable(parentErr awserr.Error) bool { + if parentErr == nil { + return false + } + + if _, ok := validParentCodes[parentErr.Code()]; !ok { + return false + } + + err := parentErr.OrigErr() if err == nil { return false } @@ -86,10 +100,8 @@ func isSerializationErrorRetryable(err error) bool { // Returns false if error is nil. func IsErrorRetryable(err error) bool { if err != nil { - if aerr, ok := err.(awserr.Error); ok && aerr.Code() != ErrCodeSerialization { - return isCodeRetryable(aerr.Code()) - } else if ok { - return isSerializationErrorRetryable(aerr.OrigErr()) + if aerr, ok := err.(awserr.Error); ok { + return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr) } } return false diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index a58e54551..c812bdff6 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.8.13" +const SDKVersion = "1.8.16" diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go index 64b6ddd3e..87584628a 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go @@ -15,7 +15,10 @@ import ( // needs to match the shape of the XML expected to be decoded. // If the shape doesn't match unmarshaling will fail. func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { - n, _ := XMLToStruct(d, nil) + n, err := XMLToStruct(d, nil) + if err != nil { + return err + } if n.Children != nil { for _, root := range n.Children { for _, c := range root { @@ -23,7 +26,7 @@ func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { c = wrappedChild[0] // pull out wrapped element } - err := parse(reflect.ValueOf(v), c, "") + err = parse(reflect.ValueOf(v), c, "") if err != nil { if err == io.EOF { return nil diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go index 3112512a2..3e970b629 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go @@ -40,11 +40,16 @@ func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) { out := &XMLNode{} for { tok, err := d.Token() - if tok == nil || err == io.EOF { - break - } if err != nil { - return out, err + if err == io.EOF { + break + } else { + return out, err + } + } + + if tok == nil { + break } switch typed := tok.(type) { diff --git a/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go b/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go index 7d281f77f..f4e0c2ed7 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go @@ -13536,6 +13536,15 @@ type GetDeploymentInput struct { // DeploymentId is a required field DeploymentId *string `location:"uri" locationName:"deployment_id" type:"string" required:"true"` + // A query parameter to retrieve the specified embedded resources of the returned + // Deployment resource in the response. In a REST API call, this embed parameter + // value is a list of comma-separated strings, as in GET /restapis/{restapi_id}/deployments/{deployment_id}?embed=var1,var2. + // The SDK and other platform-dependent libraries might use a different format + // for the list. Currently, this request supports only retrieval of the embedded + // API summary this way. Hence, the parameter value must be a single-valued + // list containing only the "apisummary" string. For example, GET /restapis/{restapi_id}/deployments/{deployment_id}?embed=apisummary. + Embed []*string `location:"querystring" locationName:"embed" type:"list"` + // The identifier of the RestApi resource for the Deployment resource to get // information about. // @@ -13575,6 +13584,12 @@ func (s *GetDeploymentInput) SetDeploymentId(v string) *GetDeploymentInput { return s } +// SetEmbed sets the Embed field's value. +func (s *GetDeploymentInput) SetEmbed(v []*string) *GetDeploymentInput { + s.Embed = v + return s +} + // SetRestApiId sets the RestApiId field's value. func (s *GetDeploymentInput) SetRestApiId(v string) *GetDeploymentInput { s.RestApiId = &v @@ -14940,6 +14955,14 @@ func (s *GetRequestValidatorsOutput) SetPosition(v string) *GetRequestValidators type GetResourceInput struct { _ struct{} `type:"structure"` + // A query parameter to retrieve the specified resources embedded in the returned + // Resource representation in the response. This embed parameter value is a + // list of comma-separated strings. Currently, the request supports only retrieval + // of the embedded Method resources this way. The query parameter value must + // be a single-valued list and contain the "methods" string. For example, GET + // /restapis/{restapi_id}/resources/{resource_id}?embed=methods. + Embed []*string `location:"querystring" locationName:"embed" type:"list"` + // The identifier for the Resource resource. // // ResourceId is a required field @@ -14977,6 +15000,12 @@ func (s *GetResourceInput) Validate() error { return nil } +// SetEmbed sets the Embed field's value. +func (s *GetResourceInput) SetEmbed(v []*string) *GetResourceInput { + s.Embed = v + return s +} + // SetResourceId sets the ResourceId field's value. func (s *GetResourceInput) SetResourceId(v string) *GetResourceInput { s.ResourceId = &v @@ -14993,6 +15022,14 @@ func (s *GetResourceInput) SetRestApiId(v string) *GetResourceInput { type GetResourcesInput struct { _ struct{} `type:"structure"` + // A query parameter used to retrieve the specified resources embedded in the + // returned Resources resource in the response. This embed parameter value is + // a list of comma-separated strings. Currently, the request supports only retrieval + // of the embedded Method resources this way. The query parameter value must + // be a single-valued list and contain the "methods" string. For example, GET + // /restapis/{restapi_id}/resources?embed=methods. + Embed []*string `location:"querystring" locationName:"embed" type:"list"` + // The maximum number of returned results per page. The value is 25 by default // and could be between 1 - 500. Limit *int64 `location:"querystring" locationName:"limit" type:"integer"` @@ -15029,6 +15066,12 @@ func (s *GetResourcesInput) Validate() error { return nil } +// SetEmbed sets the Embed field's value. +func (s *GetResourcesInput) SetEmbed(v []*string) *GetResourcesInput { + s.Embed = v + return s +} + // SetLimit sets the Limit field's value. func (s *GetResourcesInput) SetLimit(v int64) *GetResourcesInput { s.Limit = &v diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index 63e7dbc70..a18d9f9ad 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -137,8 +137,8 @@ func (c *EC2) AcceptVpcPeeringConnectionRequest(input *AcceptVpcPeeringConnectio // // Accept a VPC peering connection request. To accept a request, the VPC peering // connection must be in the pending-acceptance state, and you must be the owner -// of the peer VPC. Use the DescribeVpcPeeringConnections request to view your -// outstanding VPC peering connection requests. +// of the peer VPC. Use DescribeVpcPeeringConnections to view your outstanding +// VPC peering connection requests. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -546,12 +546,17 @@ func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *reques // // [EC2-Classic, VPC in an EC2-VPC-only account] If the Elastic IP address is // already associated with a different instance, it is disassociated from that -// instance and associated with the specified instance. +// instance and associated with the specified instance. If you associate an +// Elastic IP address with an instance that has an existing Elastic IP address, +// the existing address is disassociated from the instance, but remains allocated +// to your account. // // [VPC in an EC2-Classic account] If you don't specify a private IP address, // the Elastic IP address is associated with the primary IP address. If the // Elastic IP address is already associated with a different instance or a network -// interface, you get an error unless you allow reassociation. +// interface, you get an error unless you allow reassociation. You cannot associate +// an Elastic IP address with an instance or network interface that has an existing +// Elastic IP address. // // This is an idempotent operation. If you perform the operation more than once, // Amazon EC2 doesn't return an error, and you may be charged for each time @@ -2645,16 +2650,16 @@ func (c *EC2) CreateDhcpOptionsRequest(input *CreateDhcpOptionsInput) (req *requ // to receive a custom DNS hostname as specified in domain-name, you must // set domain-name-servers to a custom DNS server. // -// * domain-name - If you're using AmazonProvidedDNS in "us-east-1", specify -// "ec2.internal". If you're using AmazonProvidedDNS in another region, specify -// "region.compute.internal" (for example, "ap-northeast-1.compute.internal"). -// Otherwise, specify a domain name (for example, "MyCompany.com"). This -// value is used to complete unqualified DNS hostnames. Important: Some Linux -// operating systems accept multiple domain names separated by spaces. However, -// Windows and other Linux operating systems treat the value as a single -// domain, which results in unexpected behavior. If your DHCP options set -// is associated with a VPC that has instances with multiple operating systems, -// specify only one domain name. +// * domain-name - If you're using AmazonProvidedDNS in us-east-1, specify +// ec2.internal. If you're using AmazonProvidedDNS in another region, specify +// region.compute.internal (for example, ap-northeast-1.compute.internal). +// Otherwise, specify a domain name (for example, MyCompany.com). This value +// is used to complete unqualified DNS hostnames. Important: Some Linux operating +// systems accept multiple domain names separated by spaces. However, Windows +// and other Linux operating systems treat the value as a single domain, +// which results in unexpected behavior. If your DHCP options set is associated +// with a VPC that has instances with multiple operating systems, specify +// only one domain name. // // * ntp-servers - The IP addresses of up to four Network Time Protocol (NTP) // servers. @@ -2863,6 +2868,88 @@ func (c *EC2) CreateFlowLogsWithContext(ctx aws.Context, input *CreateFlowLogsIn return out, req.Send() } +const opCreateFpgaImage = "CreateFpgaImage" + +// CreateFpgaImageRequest generates a "aws/request.Request" representing the +// client's request for the CreateFpgaImage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See CreateFpgaImage for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateFpgaImage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateFpgaImageRequest method. +// req, resp := client.CreateFpgaImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage +func (c *EC2) CreateFpgaImageRequest(input *CreateFpgaImageInput) (req *request.Request, output *CreateFpgaImageOutput) { + op := &request.Operation{ + Name: opCreateFpgaImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateFpgaImageInput{} + } + + output = &CreateFpgaImageOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateFpgaImage API operation for Amazon Elastic Compute Cloud. +// +// Creates an Amazon FPGA Image (AFI) from the specified design checkpoint (DCP). +// +// The create operation is asynchronous. To verify that the AFI is ready for +// use, check the output logs. +// +// An AFI contains the FPGA bitstream that is ready to download to an FPGA. +// You can securely deploy an AFI on one or more FPGA-accelerated instances. +// For more information, see the AWS FPGA Hardware Development Kit (https://github.com/aws/aws-fpga/). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateFpgaImage for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage +func (c *EC2) CreateFpgaImage(input *CreateFpgaImageInput) (*CreateFpgaImageOutput, error) { + req, out := c.CreateFpgaImageRequest(input) + return out, req.Send() +} + +// CreateFpgaImageWithContext is the same as CreateFpgaImage with the addition of +// the ability to pass a context and additional request options. +// +// See CreateFpgaImage for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateFpgaImageWithContext(ctx aws.Context, input *CreateFpgaImageInput, opts ...request.Option) (*CreateFpgaImageOutput, error) { + req, out := c.CreateFpgaImageRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateImage = "CreateImage" // CreateImageRequest generates a "aws/request.Request" representing the @@ -4216,7 +4303,7 @@ func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *request.Reques // If you've associated an IPv6 CIDR block with your VPC, you can create a subnet // with an IPv6 CIDR block that uses a /64 prefix length. // -// AWS reserves both the first four and the last IP address in each subnet's +// AWS reserves both the first four and the last IPv4 address in each subnet's // CIDR block. They're not available for use. // // If you add more than one subnet to a VPC, they're set up in a star topology @@ -4665,8 +4752,8 @@ func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectio // peering connection. The VPC peering connection request expires after 7 days, // after which it cannot be accepted or rejected. // -// A CreateVpcPeeringConnection request between VPCs with overlapping CIDR blocks -// results in the VPC peering connection having a status of failed. +// If you try to create a VPC peering connection between VPCs that have overlapping +// CIDR blocks, the VPC peering connection status goes to failed. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -12549,8 +12636,8 @@ func (c *EC2) DescribeVpcClassicLinkDnsSupportRequest(input *DescribeVpcClassicL // the DNS hostname of a linked EC2-Classic instance resolves to its private // IP address when addressed from an instance in the VPC to which it's linked. // Similarly, the DNS hostname of an instance in a VPC resolves to its private -// IP address when addressed from a linked EC2-Classic instance. For more information -// about ClassicLink, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) +// IP address when addressed from a linked EC2-Classic instance. For more information, +// see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -13166,7 +13253,7 @@ func (c *EC2) DetachInternetGatewayRequest(input *DetachInternetGatewayInput) (r // // Detaches an Internet gateway from a VPC, disabling connectivity between the // Internet and the VPC. The VPC must not contain any running instances with -// Elastic IP addresses. +// Elastic IP addresses or public IPv4 addresses. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -23689,6 +23776,128 @@ func (s *CreateFlowLogsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *CreateFlo return s } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageRequest +type CreateFpgaImageInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier that you provide to ensure the idempotency + // of the request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // A description for the AFI. + Description *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The location of the encrypted design checkpoint in Amazon S3. The input must + // be a tarball. + // + // InputStorageLocation is a required field + InputStorageLocation *StorageLocation `type:"structure" required:"true"` + + // The location in Amazon S3 for the output logs. + LogsStorageLocation *StorageLocation `type:"structure"` + + // A name for the AFI. + Name *string `type:"string"` +} + +// String returns the string representation +func (s CreateFpgaImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFpgaImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateFpgaImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateFpgaImageInput"} + if s.InputStorageLocation == nil { + invalidParams.Add(request.NewErrParamRequired("InputStorageLocation")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateFpgaImageInput) SetClientToken(v string) *CreateFpgaImageInput { + s.ClientToken = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *CreateFpgaImageInput) SetDescription(v string) *CreateFpgaImageInput { + s.Description = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateFpgaImageInput) SetDryRun(v bool) *CreateFpgaImageInput { + s.DryRun = &v + return s +} + +// SetInputStorageLocation sets the InputStorageLocation field's value. +func (s *CreateFpgaImageInput) SetInputStorageLocation(v *StorageLocation) *CreateFpgaImageInput { + s.InputStorageLocation = v + return s +} + +// SetLogsStorageLocation sets the LogsStorageLocation field's value. +func (s *CreateFpgaImageInput) SetLogsStorageLocation(v *StorageLocation) *CreateFpgaImageInput { + s.LogsStorageLocation = v + return s +} + +// SetName sets the Name field's value. +func (s *CreateFpgaImageInput) SetName(v string) *CreateFpgaImageInput { + s.Name = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageResult +type CreateFpgaImageOutput struct { + _ struct{} `type:"structure"` + + // The global FPGA image identifier (AGFI ID). + FpgaImageGlobalId *string `locationName:"fpgaImageGlobalId" type:"string"` + + // The FPGA image identifier (AFI ID). + FpgaImageId *string `locationName:"fpgaImageId" type:"string"` +} + +// String returns the string representation +func (s CreateFpgaImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFpgaImageOutput) GoString() string { + return s.String() +} + +// SetFpgaImageGlobalId sets the FpgaImageGlobalId field's value. +func (s *CreateFpgaImageOutput) SetFpgaImageGlobalId(v string) *CreateFpgaImageOutput { + s.FpgaImageGlobalId = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *CreateFpgaImageOutput) SetFpgaImageId(v string) *CreateFpgaImageOutput { + s.FpgaImageId = &v + return s +} + // Contains the parameters for CreateImage. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageRequest type CreateImageInput struct { @@ -30587,18 +30796,6 @@ type DescribeInstancesInput struct { // // * architecture - The instance architecture (i386 | x86_64). // - // * association.public-ip - The address of the Elastic IP address (IPv4) - // bound to the network interface. - // - // * association.ip-owner-id - The owner of the Elastic IP address (IPv4) - // associated with the network interface. - // - // * association.allocation-id - The allocation ID returned when you allocated - // the Elastic IP address (IPv4) for your network interface. - // - // * association.association-id - The association ID returned when the network - // interface was associated with an IPv4 address. - // // * availability-zone - The Availability Zone of the instance. // // * block-device-mapping.attach-time - The attach time for an EBS volume @@ -30684,6 +30881,18 @@ type DescribeInstancesInput struct { // * network-interface.addresses.association.ip-owner-id - The owner ID of // the private IPv4 address associated with the network interface. // + // * network-interface.association.public-ip - The address of the Elastic + // IP address (IPv4) bound to the network interface. + // + // * network-interface.association.ip-owner-id - The owner of the Elastic + // IP address (IPv4) associated with the network interface. + // + // * network-interface.association.allocation-id - The allocation ID returned + // when you allocated the Elastic IP address (IPv4) for your network interface. + // + // * network-interface.association.association-id - The association ID returned + // when the network interface was associated with an IPv4 address. + // // * network-interface.attachment.attachment-id - The ID of the interface // attachment. // @@ -31425,7 +31634,7 @@ func (s *DescribeNetworkAclsOutput) SetNetworkAcls(v []*NetworkAcl) *DescribeNet type DescribeNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` - // The attribute of the network interface. + // The attribute of the network interface. This parameter is required. Attribute *string `locationName:"attribute" type:"string" enum:"NetworkInterfaceAttribute"` // Checks whether you have the required permissions for the action, without @@ -32355,6 +32564,9 @@ type DescribeReservedInstancesOfferingsInput struct { // with a tenancy of dedicated is applied to instances that run in a VPC on // single-tenant hardware (i.e., Dedicated Instances). // + // Important: The host value cannot be used with this parameter. Use the default + // or dedicated values only. + // // Default: default InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` @@ -32586,7 +32798,8 @@ type DescribeRouteTablesInput struct { // * association.subnet-id - The ID of the subnet involved in the association. // // * association.main - Indicates whether the route table is the main route - // table for the VPC (true | false). + // table for the VPC (true | false). Route tables that do not have an association + // ID are not returned in the response. // // * route-table-id - The ID of the route table. // @@ -34582,7 +34795,7 @@ func (s *DescribeTagsOutput) SetTags(v []*TagDescription) *DescribeTagsOutput { type DescribeVolumeAttributeInput struct { _ struct{} `type:"structure"` - // The instance attribute. + // The attribute of the volume. This parameter is required. Attribute *string `type:"string" enum:"VolumeAttributeName"` // Checks whether you have the required permissions for the action, without @@ -53953,6 +54166,40 @@ func (s *Storage) SetS3(v *S3Storage) *Storage { return s } +// Describes a storage location in Amazon S3. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StorageLocation +type StorageLocation struct { + _ struct{} `type:"structure"` + + // The name of the S3 bucket. + Bucket *string `type:"string"` + + // The key. + Key *string `type:"string"` +} + +// String returns the string representation +func (s StorageLocation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StorageLocation) GoString() string { + return s.String() +} + +// SetBucket sets the Bucket field's value. +func (s *StorageLocation) SetBucket(v string) *StorageLocation { + s.Bucket = &v + return s +} + +// SetKey sets the Key field's value. +func (s *StorageLocation) SetKey(v string) *StorageLocation { + s.Key = &v + return s +} + // Describes a subnet. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Subnet type Subnet struct { diff --git a/vendor/github.com/aws/aws-sdk-go/service/elbv2/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/elbv2/waiters.go index a958d8ed3..44fc1fc85 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/elbv2/waiters.go +++ b/vendor/github.com/aws/aws-sdk-go/service/elbv2/waiters.go @@ -115,3 +115,54 @@ func (c *ELBV2) WaitUntilLoadBalancerExistsWithContext(ctx aws.Context, input *D return w.WaitWithContext(ctx) } + +// WaitUntilLoadBalancersDeleted uses the Elastic Load Balancing v2 API operation +// DescribeLoadBalancers to wait for a condition to be met before returning. +// If the condition is not meet within the max attempt window an error will +// be returned. +func (c *ELBV2) WaitUntilLoadBalancersDeleted(input *DescribeLoadBalancersInput) error { + return c.WaitUntilLoadBalancersDeletedWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilLoadBalancersDeletedWithContext is an extended version of WaitUntilLoadBalancersDeleted. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *ELBV2) WaitUntilLoadBalancersDeletedWithContext(ctx aws.Context, input *DescribeLoadBalancersInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "WaitUntilLoadBalancersDeleted", + MaxAttempts: 40, + Delay: request.ConstantWaiterDelay(15 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.RetryWaiterState, + Matcher: request.PathAllWaiterMatch, Argument: "LoadBalancers[].State.Code", + Expected: "active", + }, + { + State: request.SuccessWaiterState, + Matcher: request.ErrorWaiterMatch, + Expected: "LoadBalancerNotFound", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *DescribeLoadBalancersInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeLoadBalancersRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/iam/api.go b/vendor/github.com/aws/aws-sdk-go/service/iam/api.go index 7bf68ca83..a36cb5d1c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/iam/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/iam/api.go @@ -160,7 +160,8 @@ func (c *IAM) AddRoleToInstanceProfileRequest(input *AddRoleToInstanceProfileInp // AddRoleToInstanceProfile API operation for AWS Identity and Access Management. // -// Adds the specified IAM role to the specified instance profile. +// Adds the specified IAM role to the specified instance profile. An instance +// profile can contain only one role, and this limit cannot be increased. // // The caller of this API must be granted the PassRole permission on the IAM // role by a permission policy. @@ -189,6 +190,12 @@ func (c *IAM) AddRoleToInstanceProfileRequest(input *AddRoleToInstanceProfileInp // The request was rejected because it attempted to create resources beyond // the current AWS account limits. The error message describes the limit exceeded. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -455,13 +462,13 @@ func (c *IAM) AttachRolePolicyRequest(input *AttachRolePolicyInput) (req *reques // AttachRolePolicy API operation for AWS Identity and Access Management. // -// Attaches the specified managed policy to the specified IAM role. +// Attaches the specified managed policy to the specified IAM role. When you +// attach a managed policy to a role, the managed policy becomes part of the +// role's permission (access) policy. // -// When you attach a managed policy to a role, the managed policy becomes part -// of the role's permission (access) policy. You cannot use a managed policy -// as the role's trust policy. The role's trust policy is created at the same -// time as the role, using CreateRole. You can update a role's trust policy -// using UpdateAssumeRolePolicy. +// You cannot use a managed policy as the role's trust policy. The role's trust +// policy is created at the same time as the role, using CreateRole. You can +// update a role's trust policy using UpdateAssumeRolePolicy. // // Use this API to attach a managed policy to a role. To embed an inline policy // in a role, use PutRolePolicy. For more information about policies, see Managed @@ -488,6 +495,12 @@ func (c *IAM) AttachRolePolicyRequest(input *AttachRolePolicyInput) (req *reques // The request was rejected because an invalid or out-of-range value was supplied // for an input parameter. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -1601,6 +1614,10 @@ func (c *IAM) CreateRoleRequest(input *CreateRoleInput) (req *request.Request, o // The request was rejected because it attempted to create resources beyond // the current AWS account limits. The error message describes the limit exceeded. // +// * ErrCodeInvalidInputException "InvalidInput" +// The request was rejected because an invalid or out-of-range value was supplied +// for an input parameter. +// // * ErrCodeEntityAlreadyExistsException "EntityAlreadyExists" // The request was rejected because it attempted to create a resource that already // exists. @@ -1749,6 +1766,112 @@ func (c *IAM) CreateSAMLProviderWithContext(ctx aws.Context, input *CreateSAMLPr return out, req.Send() } +const opCreateServiceLinkedRole = "CreateServiceLinkedRole" + +// CreateServiceLinkedRoleRequest generates a "aws/request.Request" representing the +// client's request for the CreateServiceLinkedRole operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See CreateServiceLinkedRole for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateServiceLinkedRole method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateServiceLinkedRoleRequest method. +// req, resp := client.CreateServiceLinkedRoleRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/CreateServiceLinkedRole +func (c *IAM) CreateServiceLinkedRoleRequest(input *CreateServiceLinkedRoleInput) (req *request.Request, output *CreateServiceLinkedRoleOutput) { + op := &request.Operation{ + Name: opCreateServiceLinkedRole, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateServiceLinkedRoleInput{} + } + + output = &CreateServiceLinkedRoleOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateServiceLinkedRole API operation for AWS Identity and Access Management. +// +// Creates an IAM role that is linked to a specific AWS service. The service +// controls the attached policies and when the role can be deleted. This helps +// ensure that the service is not broken by an unexpectedly changed or deleted +// role, which could put your AWS resources into an unknown state. Allowing +// the service to control the role helps improve service stability and proper +// cleanup when a service and its role are no longer needed. +// +// The name of the role is autogenerated by combining the string that you specify +// for the AWSServiceName parameter with the string that you specify for the +// CustomSuffix parameter. The resulting name must be unique in your account +// or the request fails. +// +// To attach a policy to this service-linked role, you must make the request +// using the AWS service that depends on this role. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Identity and Access Management's +// API operation CreateServiceLinkedRole for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInputException "InvalidInput" +// The request was rejected because an invalid or out-of-range value was supplied +// for an input parameter. +// +// * ErrCodeLimitExceededException "LimitExceeded" +// The request was rejected because it attempted to create resources beyond +// the current AWS account limits. The error message describes the limit exceeded. +// +// * ErrCodeNoSuchEntityException "NoSuchEntity" +// The request was rejected because it referenced an entity that does not exist. +// The error message describes the entity. +// +// * ErrCodeServiceFailureException "ServiceFailure" +// The request processing has failed because of an unknown error, exception +// or failure. +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/CreateServiceLinkedRole +func (c *IAM) CreateServiceLinkedRole(input *CreateServiceLinkedRoleInput) (*CreateServiceLinkedRoleOutput, error) { + req, out := c.CreateServiceLinkedRoleRequest(input) + return out, req.Send() +} + +// CreateServiceLinkedRoleWithContext is the same as CreateServiceLinkedRole with the addition of +// the ability to pass a context and additional request options. +// +// See CreateServiceLinkedRole for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *IAM) CreateServiceLinkedRoleWithContext(ctx aws.Context, input *CreateServiceLinkedRoleInput, opts ...request.Option) (*CreateServiceLinkedRoleOutput, error) { + req, out := c.CreateServiceLinkedRoleRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateServiceSpecificCredential = "CreateServiceSpecificCredential" // CreateServiceSpecificCredentialRequest generates a "aws/request.Request" representing the @@ -3231,6 +3354,12 @@ func (c *IAM) DeleteRoleRequest(input *DeleteRoleInput) (req *request.Request, o // The request was rejected because it attempted to create resources beyond // the current AWS account limits. The error message describes the limit exceeded. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -3328,6 +3457,12 @@ func (c *IAM) DeleteRolePolicyRequest(input *DeleteRolePolicyInput) (req *reques // The request was rejected because it attempted to create resources beyond // the current AWS account limits. The error message describes the limit exceeded. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -4299,6 +4434,12 @@ func (c *IAM) DetachRolePolicyRequest(input *DetachRolePolicyInput) (req *reques // The request was rejected because an invalid or out-of-range value was supplied // for an input parameter. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -10383,6 +10524,12 @@ func (c *IAM) PutRolePolicyRequest(input *PutRolePolicyInput) (req *request.Requ // The request was rejected because it referenced an entity that does not exist. // The error message describes the entity. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -10667,8 +10814,8 @@ func (c *IAM) RemoveRoleFromInstanceProfileRequest(input *RemoveRoleFromInstance // // Make sure you do not have any Amazon EC2 instances running with the role // you are about to remove from the instance profile. Removing a role from an -// instance profile that is associated with a running instance break any applications -// running on the instance. +// instance profile that is associated with a running instance might break any +// applications running on the instance. // // For more information about IAM roles, go to Working with Roles (http://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html). // For more information about instance profiles, go to About Instance Profiles @@ -10690,6 +10837,12 @@ func (c *IAM) RemoveRoleFromInstanceProfileRequest(input *RemoveRoleFromInstance // The request was rejected because it attempted to create resources beyond // the current AWS account limits. The error message describes the limit exceeded. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -11700,6 +11853,12 @@ func (c *IAM) UpdateAssumeRolePolicyRequest(input *UpdateAssumeRolePolicyInput) // The request was rejected because it attempted to create resources beyond // the current AWS account limits. The error message describes the limit exceeded. // +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// // * ErrCodeServiceFailureException "ServiceFailure" // The request processing has failed because of an unknown error, exception // or failure. @@ -12041,6 +12200,97 @@ func (c *IAM) UpdateOpenIDConnectProviderThumbprintWithContext(ctx aws.Context, return out, req.Send() } +const opUpdateRoleDescription = "UpdateRoleDescription" + +// UpdateRoleDescriptionRequest generates a "aws/request.Request" representing the +// client's request for the UpdateRoleDescription operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See UpdateRoleDescription for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the UpdateRoleDescription method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the UpdateRoleDescriptionRequest method. +// req, resp := client.UpdateRoleDescriptionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/UpdateRoleDescription +func (c *IAM) UpdateRoleDescriptionRequest(input *UpdateRoleDescriptionInput) (req *request.Request, output *UpdateRoleDescriptionOutput) { + op := &request.Operation{ + Name: opUpdateRoleDescription, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateRoleDescriptionInput{} + } + + output = &UpdateRoleDescriptionOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateRoleDescription API operation for AWS Identity and Access Management. +// +// Modifies the description of a role. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Identity and Access Management's +// API operation UpdateRoleDescription for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchEntityException "NoSuchEntity" +// The request was rejected because it referenced an entity that does not exist. +// The error message describes the entity. +// +// * ErrCodeUnmodifiableEntityException "UnmodifiableEntity" +// The request was rejected because only the service that depends on the service-linked +// role can modify or delete the role on your behalf. The error message includes +// the name of the service that depends on this service-linked role. You must +// request the change through that service. +// +// * ErrCodeServiceFailureException "ServiceFailure" +// The request processing has failed because of an unknown error, exception +// or failure. +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/UpdateRoleDescription +func (c *IAM) UpdateRoleDescription(input *UpdateRoleDescriptionInput) (*UpdateRoleDescriptionOutput, error) { + req, out := c.UpdateRoleDescriptionRequest(input) + return out, req.Send() +} + +// UpdateRoleDescriptionWithContext is the same as UpdateRoleDescription with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateRoleDescription for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *IAM) UpdateRoleDescriptionWithContext(ctx aws.Context, input *UpdateRoleDescriptionInput, opts ...request.Option) (*UpdateRoleDescriptionOutput, error) { + req, out := c.UpdateRoleDescriptionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opUpdateSAMLProvider = "UpdateSAMLProvider" // UpdateSAMLProviderRequest generates a "aws/request.Request" representing the @@ -13082,7 +13332,7 @@ type AccessKeyLastUsed struct { LastUsedDate *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` // The AWS region where this access key was most recently used. This field is - // null when: + // displays "N/A" when: // // * The user does not have an access key. // @@ -13098,7 +13348,7 @@ type AccessKeyLastUsed struct { Region *string `type:"string" required:"true"` // The name of the AWS service with which this access key was most recently - // used. This field is null when: + // used. This field displays "N/A" when: // // * The user does not have an access key. // @@ -13288,7 +13538,7 @@ type AddRoleToInstanceProfileInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -13534,7 +13784,7 @@ type AttachRolePolicyInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -14701,6 +14951,9 @@ type CreateRoleInput struct { // AssumeRolePolicyDocument is a required field AssumeRolePolicyDocument *string `min:"1" type:"string" required:"true"` + // A customer-provided description of the role. + Description *string `type:"string"` + // The path to the role. For more information about paths, see IAM Identifiers // (http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) // in the IAM User Guide. @@ -14719,7 +14972,8 @@ type CreateRoleInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@-. + // with no spaces. You can also include any of the following characters: _+=,.@- + // // Role names are not distinguished by case. For example, you cannot create // roles named both "PRODROLE" and "prodrole". // @@ -14768,6 +15022,12 @@ func (s *CreateRoleInput) SetAssumeRolePolicyDocument(v string) *CreateRoleInput return s } +// SetDescription sets the Description field's value. +func (s *CreateRoleInput) SetDescription(v string) *CreateRoleInput { + s.Description = &v + return s +} + // SetPath sets the Path field's value. func (s *CreateRoleInput) SetPath(v string) *CreateRoleInput { s.Path = &v @@ -14902,6 +15162,98 @@ func (s *CreateSAMLProviderOutput) SetSAMLProviderArn(v string) *CreateSAMLProvi return s } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/CreateServiceLinkedRoleRequest +type CreateServiceLinkedRoleInput struct { + _ struct{} `type:"structure"` + + // The AWS service to which this role is attached. You use a string similar + // to a URL but without the http:// in front. For example: elasticbeanstalk.amazonaws.com + // + // AWSServiceName is a required field + AWSServiceName *string `min:"1" type:"string" required:"true"` + + // A string that you provide, which is combined with the service name to form + // the complete role name. If you make multiple requests for the same service, + // then you must supply a different CustomSuffix for each request. Otherwise + // the request fails with a duplicate role name error. For example, you could + // add -1 or -debug to the suffix. + CustomSuffix *string `min:"1" type:"string"` + + // The description of the role. + Description *string `type:"string"` +} + +// String returns the string representation +func (s CreateServiceLinkedRoleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateServiceLinkedRoleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateServiceLinkedRoleInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateServiceLinkedRoleInput"} + if s.AWSServiceName == nil { + invalidParams.Add(request.NewErrParamRequired("AWSServiceName")) + } + if s.AWSServiceName != nil && len(*s.AWSServiceName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AWSServiceName", 1)) + } + if s.CustomSuffix != nil && len(*s.CustomSuffix) < 1 { + invalidParams.Add(request.NewErrParamMinLen("CustomSuffix", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAWSServiceName sets the AWSServiceName field's value. +func (s *CreateServiceLinkedRoleInput) SetAWSServiceName(v string) *CreateServiceLinkedRoleInput { + s.AWSServiceName = &v + return s +} + +// SetCustomSuffix sets the CustomSuffix field's value. +func (s *CreateServiceLinkedRoleInput) SetCustomSuffix(v string) *CreateServiceLinkedRoleInput { + s.CustomSuffix = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *CreateServiceLinkedRoleInput) SetDescription(v string) *CreateServiceLinkedRoleInput { + s.Description = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/CreateServiceLinkedRoleResponse +type CreateServiceLinkedRoleOutput struct { + _ struct{} `type:"structure"` + + // A Role object that contains details about the newly created role. + Role *Role `type:"structure"` +} + +// String returns the string representation +func (s CreateServiceLinkedRoleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateServiceLinkedRoleOutput) GoString() string { + return s.String() +} + +// SetRole sets the Role field's value. +func (s *CreateServiceLinkedRoleOutput) SetRole(v *Role) *CreateServiceLinkedRoleOutput { + s.Role = v + return s +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/CreateServiceSpecificCredentialRequest type CreateServiceSpecificCredentialInput struct { _ struct{} `type:"structure"` @@ -15197,7 +15549,7 @@ type DeactivateMFADeviceInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =/:,.@- + // with no spaces. You can also include any of the following characters: =,.@:/- // // SerialNumber is a required field SerialNumber *string `min:"9" type:"string" required:"true"` @@ -15920,7 +16272,7 @@ type DeleteRoleInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -15991,7 +16343,7 @@ type DeleteRolePolicyInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -16566,7 +16918,7 @@ type DeleteVirtualMFADeviceInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =/:,.@- + // with no spaces. You can also include any of the following characters: =,.@:/- // // SerialNumber is a required field SerialNumber *string `min:"9" type:"string" required:"true"` @@ -16718,7 +17070,7 @@ type DetachRolePolicyInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -16873,6 +17225,13 @@ type EnableMFADeviceInput struct { // // The format for this parameter is a string of 6 digits. // + // Submit your request immediately after generating the authentication codes. + // If you generate the codes and then wait too long to submit the request, the + // MFA device successfully associates with the user but the MFA device becomes + // out of sync. This happens because time-based one-time passwords (TOTP) expire + // after a short period of time. If this happens, you can resync the device + // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_sync.html). + // // AuthenticationCode1 is a required field AuthenticationCode1 *string `min:"6" type:"string" required:"true"` @@ -16880,6 +17239,13 @@ type EnableMFADeviceInput struct { // // The format for this parameter is a string of 6 digits. // + // Submit your request immediately after generating the authentication codes. + // If you generate the codes and then wait too long to submit the request, the + // MFA device successfully associates with the user but the MFA device becomes + // out of sync. This happens because time-based one-time passwords (TOTP) expire + // after a short period of time. If this happens, you can resync the device + // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_sync.html). + // // AuthenticationCode2 is a required field AuthenticationCode2 *string `min:"6" type:"string" required:"true"` @@ -16888,7 +17254,7 @@ type EnableMFADeviceInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =/:,.@- + // with no spaces. You can also include any of the following characters: =,.@:/- // // SerialNumber is a required field SerialNumber *string `min:"9" type:"string" required:"true"` @@ -17401,7 +17767,7 @@ func (s GetAccountPasswordPolicyInput) GoString() string { type GetAccountPasswordPolicyOutput struct { _ struct{} `type:"structure"` - // Contains information about the account password policy. + // A structure that contains details about the account's password policy. // // PasswordPolicy is a required field PasswordPolicy *PasswordPolicy `type:"structure" required:"true"` @@ -18348,7 +18714,7 @@ type GetRoleInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -18430,7 +18796,7 @@ type GetRolePolicyInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -19682,7 +20048,7 @@ type ListAttachedRolePoliciesInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -20540,7 +20906,7 @@ type ListInstanceProfilesForRoleInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -21257,7 +21623,7 @@ type ListRolePoliciesInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -23343,7 +23709,7 @@ type PutRolePolicyInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -23624,7 +23990,7 @@ type RemoveRoleFromInstanceProfileInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -24067,22 +24433,15 @@ func (s ResyncMFADeviceOutput) GoString() string { return s.String() } -// Contains information about an IAM role. -// -// This data type is used as a response element in the following actions: -// -// * CreateRole -// -// * GetRole -// -// * ListRoles +// Contains information about an IAM role. This structure is returned as a response +// element in several APIs that interact with roles. // Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/Role type Role struct { _ struct{} `type:"structure"` // The Amazon Resource Name (ARN) specifying the role. For more information // about ARNs and how to use them in policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) - // in the Using IAM guide. + // in the IAM User Guide guide. // // Arn is a required field Arn *string `min:"20" type:"string" required:"true"` @@ -24096,6 +24455,9 @@ type Role struct { // CreateDate is a required field CreateDate *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` + // A description of the role that you provide. + Description *string `type:"string"` + // The path to the role. For more information about paths, see IAM Identifiers // (http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html) // in the Using IAM guide. @@ -24144,6 +24506,12 @@ func (s *Role) SetCreateDate(v time.Time) *Role { return s } +// SetDescription sets the Description field's value. +func (s *Role) SetDescription(v string) *Role { + s.Description = &v + return s +} + // SetPath sets the Path field's value. func (s *Role) SetPath(v string) *Role { s.Path = &v @@ -25856,7 +26224,7 @@ type UpdateAssumeRolePolicyInput struct { // // This parameter allows (per its regex pattern (http://wikipedia.org/wiki/regex)) // a string of characters consisting of upper and lowercase alphanumeric characters - // with no spaces. You can also include any of the following characters: =,.@- + // with no spaces. You can also include any of the following characters: _+=,.@- // // RoleName is a required field RoleName *string `min:"1" type:"string" required:"true"` @@ -26187,6 +26555,86 @@ func (s UpdateOpenIDConnectProviderThumbprintOutput) GoString() string { return s.String() } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/UpdateRoleDescriptionRequest +type UpdateRoleDescriptionInput struct { + _ struct{} `type:"structure"` + + // The new description that you want to apply to the specified role. + // + // Description is a required field + Description *string `type:"string" required:"true"` + + // The name of the role that you want to modify. + // + // RoleName is a required field + RoleName *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateRoleDescriptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateRoleDescriptionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateRoleDescriptionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateRoleDescriptionInput"} + if s.Description == nil { + invalidParams.Add(request.NewErrParamRequired("Description")) + } + if s.RoleName == nil { + invalidParams.Add(request.NewErrParamRequired("RoleName")) + } + if s.RoleName != nil && len(*s.RoleName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RoleName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDescription sets the Description field's value. +func (s *UpdateRoleDescriptionInput) SetDescription(v string) *UpdateRoleDescriptionInput { + s.Description = &v + return s +} + +// SetRoleName sets the RoleName field's value. +func (s *UpdateRoleDescriptionInput) SetRoleName(v string) *UpdateRoleDescriptionInput { + s.RoleName = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/UpdateRoleDescriptionResponse +type UpdateRoleDescriptionOutput struct { + _ struct{} `type:"structure"` + + // A structure that contains details about the modified role. + Role *Role `type:"structure"` +} + +// String returns the string representation +func (s UpdateRoleDescriptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateRoleDescriptionOutput) GoString() string { + return s.String() +} + +// SetRole sets the Role field's value. +func (s *UpdateRoleDescriptionOutput) SetRole(v *Role) *UpdateRoleDescriptionOutput { + s.Role = v + return s +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/UpdateSAMLProviderRequest type UpdateSAMLProviderInput struct { _ struct{} `type:"structure"` @@ -27352,7 +27800,7 @@ type VirtualMFADevice struct { // SerialNumber is a required field SerialNumber *string `min:"9" type:"string" required:"true"` - // The user to whom the MFA device is assigned. + // The IAM user associated with this virtual MFA device. User *User `type:"structure"` } diff --git a/vendor/github.com/aws/aws-sdk-go/service/iam/errors.go b/vendor/github.com/aws/aws-sdk-go/service/iam/errors.go index fd2303523..97ad363c8 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/iam/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/iam/errors.go @@ -160,6 +160,15 @@ const ( // The specified service does not support service-specific credentials. ErrCodeServiceNotSupportedException = "NotSupportedService" + // ErrCodeUnmodifiableEntityException for service response error code + // "UnmodifiableEntity". + // + // The request was rejected because only the service that depends on the service-linked + // role can modify or delete the role on your behalf. The error message includes + // the name of the service that depends on this service-linked role. You must + // request the change through that service. + ErrCodeUnmodifiableEntityException = "UnmodifiableEntity" + // ErrCodeUnrecognizedPublicKeyEncodingException for service response error code // "UnrecognizedPublicKeyEncoding". // diff --git a/vendor/github.com/aws/aws-sdk-go/service/kinesis/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/kinesis/waiters.go index 14e2ba9e2..a64a77af6 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/kinesis/waiters.go +++ b/vendor/github.com/aws/aws-sdk-go/service/kinesis/waiters.go @@ -54,3 +54,49 @@ func (c *Kinesis) WaitUntilStreamExistsWithContext(ctx aws.Context, input *Descr return w.WaitWithContext(ctx) } + +// WaitUntilStreamNotExists uses the Kinesis API operation +// DescribeStream to wait for a condition to be met before returning. +// If the condition is not meet within the max attempt window an error will +// be returned. +func (c *Kinesis) WaitUntilStreamNotExists(input *DescribeStreamInput) error { + return c.WaitUntilStreamNotExistsWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilStreamNotExistsWithContext is an extended version of WaitUntilStreamNotExists. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Kinesis) WaitUntilStreamNotExistsWithContext(ctx aws.Context, input *DescribeStreamInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "WaitUntilStreamNotExists", + MaxAttempts: 18, + Delay: request.ConstantWaiterDelay(10 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.ErrorWaiterMatch, + Expected: "ResourceNotFoundException", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *DescribeStreamInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeStreamRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/kms/api.go b/vendor/github.com/aws/aws-sdk-go/service/kms/api.go index 82ef66120..c7e0da513 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/kms/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/kms/api.go @@ -1544,7 +1544,7 @@ func (c *KMS) GenerateDataKeyRequest(input *GenerateDataKeyInput) (req *request. // data key from memory. // // To return only an encrypted copy of the data key, use GenerateDataKeyWithoutPlaintext. -// To return an arbitrary unpredictable byte string, use GenerateRandom. +// To return a random byte string that is cryptographically secure, use GenerateRandom. // // If you use the optional EncryptionContext field, you must store at least // enough information to be able to reconstruct the full encryption context @@ -1786,7 +1786,11 @@ func (c *KMS) GenerateRandomRequest(input *GenerateRandomInput) (req *request.Re // GenerateRandom API operation for AWS Key Management Service. // -// Generates an unpredictable byte string. +// Returns a random byte string that is cryptographically secure. +// +// For more information about entropy and random number generation, see the +// AWS Key Management Service Cryptographic Details (https://d0.awsstatic.com/whitepapers/KMS-Cryptographic-Details.pdf) +// whitepaper. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4316,11 +4320,9 @@ func (s CreateAliasOutput) GoString() string { type CreateGrantInput struct { _ struct{} `type:"structure"` - // The conditions under which the operations permitted by the grant are allowed. - // - // You can use this value to allow the operations permitted by the grant only - // when a specified encryption context is present. For more information, see - // Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html) + // A structure that you can use to allow certain operations in the grant only + // when the desired encryption context is present. For more information about + // encryption context, see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html) // in the AWS Key Management Service Developer Guide. Constraints *GrantConstraints `type:"structure"` @@ -5700,7 +5702,7 @@ func (s *GenerateRandomInput) SetNumberOfBytes(v int64) *GenerateRandomInput { type GenerateRandomOutput struct { _ struct{} `type:"structure"` - // The unpredictable byte string. + // The random byte string. // // Plaintext is automatically base64 encoded/decoded by the SDK. Plaintext []byte `min:"1" type:"blob"` @@ -6023,29 +6025,34 @@ func (s *GetParametersForImportOutput) SetPublicKey(v []byte) *GetParametersForI return s } -// A structure for specifying the conditions under which the operations permitted -// by the grant are allowed. -// -// You can use this structure to allow the operations permitted by the grant -// only when a specified encryption context is present. For more information -// about encryption context, see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html) +// A structure that you can use to allow certain operations in the grant only +// when the desired encryption context is present. For more information about +// encryption context, see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html) // in the AWS Key Management Service Developer Guide. +// +// Grant constraints apply only to operations that accept encryption context +// as input. For example, the DescribeKey operation does not accept encryption +// context as input. A grant that allows the DescribeKey operation does so regardless +// of the grant constraints. In constrast, the Encrypt operation accepts encryption +// context as input. A grant that allows the Encrypt operation does so only +// when the encryption context of the Encrypt operation satisfies the grant +// constraints. // Please also see https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GrantConstraints type GrantConstraints struct { _ struct{} `type:"structure"` - // Contains a list of key-value pairs that must be present in the encryption - // context of a subsequent operation permitted by the grant. When a subsequent - // operation permitted by the grant includes an encryption context that matches - // this list, the grant allows the operation. Otherwise, the operation is not - // allowed. + // A list of key-value pairs that must be present in the encryption context + // of certain subsequent operations that the grant allows. When certain subsequent + // operations allowed by the grant include encryption context that matches this + // list, the grant allows the operation. Otherwise, the grant does not allow + // the operation. EncryptionContextEquals map[string]*string `type:"map"` - // Contains a list of key-value pairs, a subset of which must be present in - // the encryption context of a subsequent operation permitted by the grant. - // When a subsequent operation permitted by the grant includes an encryption - // context that matches this list or is a subset of this list, the grant allows - // the operation. Otherwise, the operation is not allowed. + // A list of key-value pairs, all of which must be present in the encryption + // context of certain subsequent operations that the grant allows. When certain + // subsequent operations allowed by the grant include encryption context that + // matches this list or is a superset of this list, the grant allows the operation. + // Otherwise, the grant does not allow the operation. EncryptionContextSubset map[string]*string `type:"map"` } @@ -6076,7 +6083,8 @@ func (s *GrantConstraints) SetEncryptionContextSubset(v map[string]*string) *Gra type GrantListEntry struct { _ struct{} `type:"structure"` - // The conditions under which the grant's operations are allowed. + // A list of key-value pairs that must be present in the encryption context + // of certain subsequent operations that the grant allows. Constraints *GrantConstraints `type:"structure"` // The date and time when the grant was created. diff --git a/vendor/github.com/aws/aws-sdk-go/service/lambda/api.go b/vendor/github.com/aws/aws-sdk-go/service/lambda/api.go index 2189b20a3..7602de111 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/lambda/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/lambda/api.go @@ -3035,14 +3035,14 @@ type AddPermissionInput struct { // you don't specify the SourceArn) owned by a specific account. SourceAccount *string `type:"string"` - // This is optional; however, when granting a source permission to invoke your - // function, you should specify this field with the Amazon Resource Name (ARN) - // as its value. This ensures that only events generated from the specified - // source can invoke the function. + // This is optional; however, when granting permission to invoke your function, + // you should specify this field with the Amazon Resource Name (ARN) as its + // value. This ensures that only events generated from the specified source + // can invoke the function. // - // If you add a permission for the source without providing the source ARN, - // any AWS account that creates a mapping to your function ARN can send events - // to invoke your Lambda function from that source. + // If you add a permission without providing the source ARN, any AWS account + // that creates a mapping to your function ARN can send events to invoke your + // Lambda function. SourceArn *string `type:"string"` // A unique statement identifier. @@ -3439,7 +3439,7 @@ type CreateFunctionInput struct { // Code is a required field Code *FunctionCode `type:"structure" required:"true"` - // The parent object that contains the target Amazon Resource Name (ARN) of + // The parent object that contains the target ARN (Amazon Resource Name) of // an Amazon SQS queue or Amazon SNS topic. DeadLetterConfig *DeadLetterConfig `type:"structure"` @@ -3514,6 +3514,9 @@ type CreateFunctionInput struct { // value based on your expected execution time. The default is 3 seconds. Timeout *int64 `min:"1" type:"integer"` + // The parent object that contains your function's tracing settings. + TracingConfig *TracingConfig `type:"structure"` + // If your Lambda function accesses resources in a VPC, you provide this parameter // identifying the list of security group IDs and subnet IDs. These must belong // to the same VPC. You must provide at least one security group and one subnet @@ -3648,13 +3651,19 @@ func (s *CreateFunctionInput) SetTimeout(v int64) *CreateFunctionInput { return s } +// SetTracingConfig sets the TracingConfig field's value. +func (s *CreateFunctionInput) SetTracingConfig(v *TracingConfig) *CreateFunctionInput { + s.TracingConfig = v + return s +} + // SetVpcConfig sets the VpcConfig field's value. func (s *CreateFunctionInput) SetVpcConfig(v *VpcConfig) *CreateFunctionInput { s.VpcConfig = v return s } -// The parent object that contains the target Amazon Resource Name (ARN) of +// The parent object that contains the target ARN (Amazon Resource Name) of // an Amazon SQS queue or Amazon SNS topic. type DeadLetterConfig struct { _ struct{} `type:"structure"` @@ -4191,7 +4200,7 @@ type FunctionConfiguration struct { // The size, in bytes, of the function .zip file you uploaded. CodeSize *int64 `type:"long"` - // The parent object that contains the target Amazon Resource Name (ARN) of + // The parent object that contains the target ARN (Amazon Resource Name) of // an Amazon SQS queue or Amazon SNS topic. DeadLetterConfig *DeadLetterConfig `type:"structure"` @@ -4236,6 +4245,9 @@ type FunctionConfiguration struct { // value based on your expected execution time. The default is 3 seconds. Timeout *int64 `min:"1" type:"integer"` + // The parent object that contains your function's tracing settings. + TracingConfig *TracingConfigResponse `type:"structure"` + // The version of the Lambda function. Version *string `min:"1" type:"string"` @@ -4337,6 +4349,12 @@ func (s *FunctionConfiguration) SetTimeout(v int64) *FunctionConfiguration { return s } +// SetTracingConfig sets the TracingConfig field's value. +func (s *FunctionConfiguration) SetTracingConfig(v *TracingConfigResponse) *FunctionConfiguration { + s.TracingConfig = v + return s +} + // SetVersion sets the Version field's value. func (s *FunctionConfiguration) SetVersion(v string) *FunctionConfiguration { s.Version = &v @@ -5718,6 +5736,58 @@ func (s TagResourceOutput) GoString() string { return s.String() } +// The parent object that contains your function's tracing settings. +type TracingConfig struct { + _ struct{} `type:"structure"` + + // Can be either PassThrough or Active. If PassThrough, Lambda will only trace + // the request from an upstream service if it contains a tracing header with + // "sampled=1". If Active, Lambda will respect any tracing header it receives + // from an upstream service. If no tracing header is received, Lambda will call + // X-Ray for a tracing decision. + Mode *string `type:"string" enum:"TracingMode"` +} + +// String returns the string representation +func (s TracingConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TracingConfig) GoString() string { + return s.String() +} + +// SetMode sets the Mode field's value. +func (s *TracingConfig) SetMode(v string) *TracingConfig { + s.Mode = &v + return s +} + +// Parent object of the tracing information associated with your Lambda function. +type TracingConfigResponse struct { + _ struct{} `type:"structure"` + + // The tracing mode associated with your Lambda function. + Mode *string `type:"string" enum:"TracingMode"` +} + +// String returns the string representation +func (s TracingConfigResponse) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TracingConfigResponse) GoString() string { + return s.String() +} + +// SetMode sets the Mode field's value. +func (s *TracingConfigResponse) SetMode(v string) *TracingConfigResponse { + s.Mode = &v + return s +} + type UntagResourceInput struct { _ struct{} `type:"structure"` @@ -6067,7 +6137,7 @@ func (s *UpdateFunctionCodeInput) SetZipFile(v []byte) *UpdateFunctionCodeInput type UpdateFunctionConfigurationInput struct { _ struct{} `type:"structure"` - // The parent object that contains the target Amazon Resource Name (ARN) of + // The parent object that contains the target ARN (Amazon Resource Name) of // an Amazon SQS queue or Amazon SNS topic. DeadLetterConfig *DeadLetterConfig `type:"structure"` @@ -6127,6 +6197,9 @@ type UpdateFunctionConfigurationInput struct { // value based on your expected execution time. The default is 3 seconds. Timeout *int64 `min:"1" type:"integer"` + // The parent object that contains your function's tracing settings. + TracingConfig *TracingConfig `type:"structure"` + // If your Lambda function accesses resources in a VPC, you provide this parameter // identifying the list of security group IDs and subnet IDs. These must belong // to the same VPC. You must provide at least one security group and one subnet @@ -6226,6 +6299,12 @@ func (s *UpdateFunctionConfigurationInput) SetTimeout(v int64) *UpdateFunctionCo return s } +// SetTracingConfig sets the TracingConfig field's value. +func (s *UpdateFunctionConfigurationInput) SetTracingConfig(v *TracingConfig) *UpdateFunctionConfigurationInput { + s.TracingConfig = v + return s +} + // SetVpcConfig sets the VpcConfig field's value. func (s *UpdateFunctionConfigurationInput) SetVpcConfig(v *VpcConfig) *UpdateFunctionConfigurationInput { s.VpcConfig = v @@ -6376,3 +6455,11 @@ const ( // ThrottleReasonCallerRateLimitExceeded is a ThrottleReason enum value ThrottleReasonCallerRateLimitExceeded = "CallerRateLimitExceeded" ) + +const ( + // TracingModeActive is a TracingMode enum value + TracingModeActive = "Active" + + // TracingModePassThrough is a TracingMode enum value + TracingModePassThrough = "PassThrough" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/api.go b/vendor/github.com/aws/aws-sdk-go/service/route53/api.go index d967d9bb5..58aadd605 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/route53/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/api.go @@ -62,11 +62,6 @@ func (c *Route53) AssociateVPCWithHostedZoneRequest(input *AssociateVPCWithHoste // To perform the association, the VPC and the private hosted zone must already // exist. You can't convert a public hosted zone into a private hosted zone. // -// Send a POST request to the /2013-04-01/hostedzone/hosted zone ID/associatevpc -// resource. The request body must include a document with an AssociateVPCWithHostedZoneRequest -// element. The response contains a ChangeInfo data type that you can use to -// track the progress of the request. -// // If you want to associate a VPC that was created by using one AWS account // with a private hosted zone that was created by using a different account, // the AWS account that created the private hosted zone must first submit a @@ -176,10 +171,11 @@ func (c *Route53) ChangeResourceRecordSetsRequest(input *ChangeResourceRecordSet // ChangeResourceRecordSets API operation for Amazon Route 53. // -// Create, change, update, or delete authoritative DNS information on all Amazon -// Route 53 servers. Send a POST request to: -// -// /2013-04-01/hostedzone/Amazon Route 53 hosted Zone ID/rrset resource. +// Creates, changes, or deletes a resource record set, which contains authoritative +// DNS information for a specified domain name or subdomain name. For example, +// you can use ChangeResourceRecordSets to create a resource record set that +// routes traffic for test.example.com to a web server that has an IP address +// of 192.0.2.44. // // Change Batches and Transactional Changes // @@ -454,12 +450,10 @@ func (c *Route53) CreateHealthCheckRequest(input *CreateHealthCheckInput) (req * // // Creates a new health check. // -// To create a new health check, send a POST request to the /2013-04-01/healthcheck -// resource. The request body must include a document with a CreateHealthCheckRequest -// element. The response returns the CreateHealthCheckResponse element, containing -// the health check ID specified when adding health check to a resource record -// set. For information about adding health checks to resource record sets, -// see ResourceRecordSet$HealthCheckId in ChangeResourceRecordSets. +// For information about adding health checks to resource record sets, see ResourceRecordSet$HealthCheckId +// in ChangeResourceRecordSets. +// +// ELB Load Balancers // // If you're registering EC2 instances with an Elastic Load Balancing (ELB) // load balancer, do not create Amazon Route 53 health checks for the EC2 instances. @@ -467,6 +461,8 @@ func (c *Route53) CreateHealthCheckRequest(input *CreateHealthCheckInput) (req * // for an ELB health check, which performs a similar function to an Amazon Route // 53 health check. // +// Private Hosted Zones +// // You can associate health checks with failover resource record sets in a private // hosted zone. Note the following: // @@ -500,8 +496,14 @@ func (c *Route53) CreateHealthCheckRequest(input *CreateHealthCheckInput) (req * // // * ErrCodeHealthCheckAlreadyExists "HealthCheckAlreadyExists" // The health check you're attempting to create already exists. Amazon Route -// 53 returns this error when a health check has already been created with the -// specified value for CallerReference. +// 53 returns this error when you submit a request that has the following values: +// +// * The same value for CallerReference as an existing health check, and +// one or more values that differ from the existing health check that has +// the same caller reference. +// +// * The same value for CallerReference as a health check that you created +// and later deleted, regardless of the other settings in the request. // // * ErrCodeInvalidInput "InvalidInput" // The input is not valid. @@ -573,20 +575,15 @@ func (c *Route53) CreateHostedZoneRequest(input *CreateHostedZoneInput) (req *re // CreateHostedZone API operation for Amazon Route 53. // -// Creates a new public hosted zone, used to specify how the Domain Name System -// (DNS) routes traffic on the Internet for a domain, such as example.com, and -// its subdomains. +// Creates a new public hosted zone, which you use to specify how the Domain +// Name System (DNS) routes traffic on the Internet for a domain, such as example.com, +// and its subdomains. // -// Public hosted zones can't be converted to a private hosted zone or vice versa. -// Instead, create a new hosted zone with the same name and create new resource -// record sets. +// You can't convert a public hosted zones to a private hosted zone or vice +// versa. Instead, you must create a new hosted zone with the same name and +// create new resource record sets. // -// Send a POST request to the /2013-04-01/hostedzone resource. The request body -// must include a document with a CreateHostedZoneRequest element. The response -// returns the CreateHostedZoneResponse element containing metadata about the -// hosted zone. -// -// Fore more information about charges for hosted zones, see Amazon Route 53 +// For more information about charges for hosted zones, see Amazon Route 53 // Pricing (http://aws.amazon.com/route53/pricing/). // // Note the following: @@ -599,20 +596,20 @@ func (c *Route53) CreateHostedZoneRequest(input *CreateHostedZoneInput) (req *re // (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/SOA-NSrecords.html) // in the Amazon Route 53 Developer Guide. // +// If you want to use the same name servers for multiple hosted zones, you can +// optionally associate a reusable delegation set with the hosted zone. See +// the DelegationSetId element. +// // * If your domain is registered with a registrar other than Amazon Route // 53, you must update the name servers with your registrar to make Amazon // Route 53 your DNS service. For more information, see Configuring Amazon // Route 53 as your DNS Service (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/creating-migrating.html) -// in the Amazon Route 53 Developer's Guide. +// in the Amazon Route 53 Developer Guide. // -// After creating a zone, its initial status is PENDING. This means that it -// is not yet available on all DNS servers. The status of the zone changes to -// INSYNC when the NS and SOA records are available on all Amazon Route 53 DNS -// servers. -// -// When trying to create a hosted zone using a reusable delegation set, specify -// an optional DelegationSetId, and Amazon Route 53 would assign those 4 NS -// records for the zone, instead of allotting a new one. +// When you submit a CreateHostedZone request, the initial status of the hosted +// zone is PENDING. This means that the NS and SOA records are not yet available +// on all Amazon Route 53 DNS servers. When the NS and SOA records are available, +// the status of the zone changes to INSYNC. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -733,14 +730,10 @@ func (c *Route53) CreateReusableDelegationSetRequest(input *CreateReusableDelega // by multiple hosted zones. If a hosted zoned ID is specified, CreateReusableDelegationSet // marks the delegation set associated with that zone as reusable // -// Send a POST request to the /2013-04-01/delegationset resource. The request -// body must include a document with a CreateReusableDelegationSetRequest element. +// A reusable delegation set can't be associated with a private hosted zone. // -// A reusable delegation set can't be associated with a private hosted zone/ -// -// For more information, including a procedure on how to create and configure -// a reusable delegation set (also known as white label name servers), see Configuring -// White Label Name Servers (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/white-label-name-servers.html). +// For information on how to use a reusable delegation set to configure white +// label name servers, see Configuring White Label Name Servers (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/white-label-name-servers.html). // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -847,11 +840,6 @@ func (c *Route53) CreateTrafficPolicyRequest(input *CreateTrafficPolicyInput) (r // sets for one domain name (such as example.com) or one subdomain name (such // as www.example.com). // -// Send a POST request to the /2013-04-01/trafficpolicy resource. The request -// body must include a document with a CreateTrafficPolicyRequest element. The -// response includes the CreateTrafficPolicyResponse element, which contains -// information about the new traffic policy. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -949,11 +937,6 @@ func (c *Route53) CreateTrafficPolicyInstanceRequest(input *CreateTrafficPolicyI // responds to DNS queries for the domain or subdomain name by using the resource // record sets that CreateTrafficPolicyInstance created. // -// Send a POST request to the /2013-04-01/trafficpolicyinstance resource. The -// request body must include a document with a CreateTrafficPolicyRequest element. -// The response returns the CreateTrafficPolicyInstanceResponse element, which -// contains information about the traffic policy instance. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -1055,11 +1038,6 @@ func (c *Route53) CreateTrafficPolicyVersionRequest(input *CreateTrafficPolicyVe // the limit and need to create another version, you'll need to start a new // traffic policy. // -// Send a POST request to the /2013-04-01/trafficpolicy/ resource. The request -// body includes a document with a CreateTrafficPolicyVersionRequest element. -// The response returns the CreateTrafficPolicyVersionResponse element, which -// contains information about the new version of the traffic policy. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -1160,10 +1138,6 @@ func (c *Route53) CreateVPCAssociationAuthorizationRequest(input *CreateVPCAssoc // with a hosted zone that you created by using a different account, you must // submit one authorization request for each VPC. // -// Send a POST request to the /2013-04-01/hostedzone/hosted zone ID/authorizevpcassociation -// resource. The request body must include a document with a CreateVPCAssociationAuthorizationRequest -// element. The response contains information about the authorization. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -1260,8 +1234,7 @@ func (c *Route53) DeleteHealthCheckRequest(input *DeleteHealthCheckInput) (req * // DeleteHealthCheck API operation for Amazon Route 53. // -// Deletes a health check. Send a DELETE request to the /2013-04-01/healthcheck/health -// check ID resource. +// Deletes a health check. // // Amazon Route 53 does not prevent you from deleting a health check even if // the health check is associated with one or more resource record sets. If @@ -1358,16 +1331,37 @@ func (c *Route53) DeleteHostedZoneRequest(input *DeleteHostedZoneInput) (req *re // DeleteHostedZone API operation for Amazon Route 53. // -// Deletes a hosted zone. Send a DELETE request to the /Amazon Route 53 API -// version/hostedzone/hosted zone ID resource. +// Deletes a hosted zone. // -// Delete a hosted zone only if there are no resource record sets other than -// the default SOA record and NS resource record sets. If the hosted zone contains -// other resource record sets, delete them before deleting the hosted zone. -// If you try to delete a hosted zone that contains other resource record sets, -// Amazon Route 53 denies your request with a HostedZoneNotEmpty error. For +// If the name servers for the hosted zone are associated with a domain and +// if you want to make the domain unavailable on the Internet, we recommend +// that you delete the name servers from the domain to prevent future DNS queries +// from possibly being misrouted. If the domain is registered with Amazon Route +// 53, see UpdateDomainNameservers. If the domain is registered with another +// registrar, use the method provided by the registrar to delete name servers +// for the domain. +// +// Some domain registries don't allow you to remove all of the name servers +// for a domain. If the registry for your domain requires one or more name servers, +// we recommend that you delete the hosted zone only if you transfer DNS service +// to another service provider, and you replace the name servers for the domain +// with name servers from the new provider. +// +// You can delete a hosted zone only if it contains only the default SOA record +// and NS resource record sets. If the hosted zone contains other resource record +// sets, you must delete them before you can delete the hosted zone. If you +// try to delete a hosted zone that contains other resource record sets, the +// request fails, and Amazon Route 53 returns a HostedZoneNotEmpty error. For // information about deleting records from your hosted zone, see ChangeResourceRecordSets. // +// To verify that the hosted zone has been deleted, do one of the following: +// +// * Use the GetHostedZone action to request information about the hosted +// zone. +// +// * Use the ListHostedZones action to get a list of the hosted zones associated +// with the current AWS account. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -1462,14 +1456,13 @@ func (c *Route53) DeleteReusableDelegationSetRequest(input *DeleteReusableDelega // DeleteReusableDelegationSet API operation for Amazon Route 53. // -// Deletes a reusable delegation set. Send a DELETE request to the /2013-04-01/delegationset/delegation -// set ID resource. +// Deletes a reusable delegation set. // -// You can delete a reusable delegation set only if there are no associated -// hosted zones. +// You can delete a reusable delegation set only if it isn't associated with +// any hosted zones. // // To verify that the reusable delegation set is not associated with any hosted -// zones, run the GetReusableDelegationSet action and specify the ID of the +// zones, submit a GetReusableDelegationSet request and specify the ID of the // reusable delegation set that you want to delete. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -1562,8 +1555,6 @@ func (c *Route53) DeleteTrafficPolicyRequest(input *DeleteTrafficPolicyInput) (r // // Deletes a traffic policy. // -// Send a DELETE request to the /Amazon Route 53 API version/trafficpolicy resource. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -1656,9 +1647,6 @@ func (c *Route53) DeleteTrafficPolicyInstanceRequest(input *DeleteTrafficPolicyI // Deletes a traffic policy instance and all of the resource record sets that // Amazon Route 53 created when you created the instance. // -// Send a DELETE request to the /Amazon Route 53 API version/trafficpolicy/traffic -// policy instance ID resource. -// // In the Amazon Route 53 console, traffic policy instances are known as policy // records. // @@ -1761,10 +1749,6 @@ func (c *Route53) DeleteVPCAssociationAuthorizationRequest(input *DeleteVPCAssoc // won't disassociate the VPC from the hosted zone. If you want to delete an // existing association, use DisassociateVPCFromHostedZone. // -// Send a DELETE request to the /2013-04-01/hostedzone/hosted zone ID/deauthorizevpcassociation -// resource. The request body must include a document with a DeleteVPCAssociationAuthorizationRequest -// element. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -1862,10 +1846,6 @@ func (c *Route53) DisassociateVPCFromHostedZoneRequest(input *DisassociateVPCFro // // You can't disassociate the last VPC from a private hosted zone. // -// Send a POST request to the /2013-04-01/hostedzone/hosted zone ID/disassociatevpc -// resource. The request body must include a document with a DisassociateVPCFromHostedZoneRequest -// element. The response includes a DisassociateVPCFromHostedZoneResponse element. -// // You can't disassociate a VPC from a private hosted zone when only one VPC // is associated with the hosted zone. You also can't convert a private hosted // zone into a public hosted zone. @@ -1966,11 +1946,11 @@ func (c *Route53) GetChangeRequest(input *GetChangeInput) (req *request.Request, // Returns the current status of a change batch request. The status is one of // the following values: // -// * PENDING indicates that the changes in this request have not replicated +// * PENDING indicates that the changes in this request have not propagated // to all Amazon Route 53 DNS servers. This is the initial status of all // change batch requests. // -// * INSYNC indicates that the changes have replicated to all Amazon Route +// * INSYNC indicates that the changes have propagated to all Amazon Route // 53 DNS servers. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -2132,9 +2112,24 @@ func (c *Route53) GetGeoLocationRequest(input *GetGeoLocationInput) (req *reques // GetGeoLocation API operation for Amazon Route 53. // -// Retrieves a single geo location. Send a GET request to the /2013-04-01/geolocation -// resource with one of these options: continentcode | countrycode | countrycode -// and subdivisioncode. +// Gets information about whether a specified geographic location is supported +// for Amazon Route 53 geolocation resource record sets. +// +// Use the following syntax to determine whether a continent is supported for +// geolocation: +// +// GET /2013-04-01/geolocation?ContinentCode=two-letter abbreviation for a continent +// +// Use the following syntax to determine whether a country is supported for +// geolocation: +// +// GET /2013-04-01/geolocation?CountryCode=two-character country code +// +// Use the following syntax to determine whether a subdivision of a country +// is supported for geolocation: +// +// GET /2013-04-01/geolocation?CountryCode=two-character country code&SubdivisionCode=subdivision +// code // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2217,11 +2212,7 @@ func (c *Route53) GetHealthCheckRequest(input *GetHealthCheckInput) (req *reques // GetHealthCheck API operation for Amazon Route 53. // -// Gets information about a specified health check. Send a GET request to the -// /2013-04-01/healthcheck/health check ID resource. For more information about -// using the console to perform this operation, see Amazon Route 53 Health Checks -// and DNS Failover (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html) -// in the Amazon Route 53 Developer Guide. +// Gets information about a specified health check. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2309,8 +2300,8 @@ func (c *Route53) GetHealthCheckCountRequest(input *GetHealthCheckCountInput) (r // GetHealthCheckCount API operation for Amazon Route 53. // -// To retrieve a count of all your health checks, send a GET request to the -// /2013-04-01/healthcheckcount resource. +// Retrieves the number of health checks that are associated with the current +// AWS account. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2385,10 +2376,7 @@ func (c *Route53) GetHealthCheckLastFailureReasonRequest(input *GetHealthCheckLa // GetHealthCheckLastFailureReason API operation for Amazon Route 53. // -// If you want to learn why a health check is currently failing or why it failed -// most recently (if at all), you can get the failure reason for the most recent -// failure. Send a GET request to the /Amazon Route 53 API version/healthcheck/health -// check ID/lastfailurereason resource. +// Gets the reason that a specified health check failed most recently. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2472,9 +2460,7 @@ func (c *Route53) GetHealthCheckStatusRequest(input *GetHealthCheckStatusInput) // GetHealthCheckStatus API operation for Amazon Route 53. // -// Gets status of a specified health check. Send a GET request to the /2013-04-01/healthcheck/health -// check ID/status resource. You can use this call to get a health check's current -// status. +// Gets status of a specified health check. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2558,9 +2544,8 @@ func (c *Route53) GetHostedZoneRequest(input *GetHostedZoneInput) (req *request. // GetHostedZone API operation for Amazon Route 53. // -// Retrieves the delegation set for a hosted zone, including the four name servers -// assigned to the hosted zone. Send a GET request to the /Amazon Route 53 API -// version/hostedzone/hosted zone ID resource. +// Gets information about a specified hosted zone including the four name servers +// assigned to the hosted zone. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2643,8 +2628,8 @@ func (c *Route53) GetHostedZoneCountRequest(input *GetHostedZoneCountInput) (req // GetHostedZoneCount API operation for Amazon Route 53. // -// Retrieves a count of all your hosted zones. Send a GET request to the /2013-04-01/hostedzonecount -// resource. +// Retrieves the number of hosted zones that are associated with the current +// AWS account. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2724,8 +2709,8 @@ func (c *Route53) GetReusableDelegationSetRequest(input *GetReusableDelegationSe // GetReusableDelegationSet API operation for Amazon Route 53. // -// Retrieves the reusable delegation set. Send a GET request to the /2013-04-01/delegationset/delegation -// set ID resource. +// Retrieves information about a specified reusable delegation set, including +// the four name servers that are assigned to the delegation set. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2813,8 +2798,6 @@ func (c *Route53) GetTrafficPolicyRequest(input *GetTrafficPolicyInput) (req *re // // Gets information about a specific traffic policy version. // -// Send a GET request to the /Amazon Route 53 API version/trafficpolicy resource. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -2898,9 +2881,6 @@ func (c *Route53) GetTrafficPolicyInstanceRequest(input *GetTrafficPolicyInstanc // // Gets information about a specified traffic policy instance. // -// Send a GET request to the /Amazon Route 53 API version/trafficpolicyinstance -// resource. -// // After you submit a CreateTrafficPolicyInstance or an UpdateTrafficPolicyInstance // request, there's a brief delay while Amazon Route 53 creates the resource // record sets that are specified in the traffic policy definition. For more @@ -2993,9 +2973,6 @@ func (c *Route53) GetTrafficPolicyInstanceCountRequest(input *GetTrafficPolicyIn // Gets the number of traffic policy instances that are associated with the // current AWS account. // -// To get the number of traffic policy instances, send a GET request to the -// /2013-04-01/trafficpolicyinstancecount resource. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -3069,9 +3046,7 @@ func (c *Route53) ListGeoLocationsRequest(input *ListGeoLocationsInput) (req *re // ListGeoLocations API operation for Amazon Route 53. // -// Retrieves a list of supported geo locations. Send a GET request to the /2013-04-01/geolocations -// resource. The response to this request includes a GeoLocationDetailsList -// element for each location that Amazon Route 53 supports. +// Retrieves a list of supported geo locations. // // Countries are listed first, and continents are listed last. If Amazon Route // 53 supports subdivisions for a country (for example, states or provinces), @@ -3162,15 +3137,8 @@ func (c *Route53) ListHealthChecksRequest(input *ListHealthChecksInput) (req *re // ListHealthChecks API operation for Amazon Route 53. // -// Retrieve a list of your health checks. Send a GET request to the /2013-04-01/healthcheck -// resource. The response to this request includes a HealthChecks element with -// zero or more HealthCheck child elements. By default, the list of health checks -// is displayed on a single page. You can control the length of the page that -// is displayed by using the MaxItems parameter. You can use the Marker parameter -// to control the health check that the list begins with. -// -// For information about listing health checks using the Amazon Route 53 console, -// see Amazon Route 53 Health Checks and DNS Failover (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html). +// Retrieve a list of the health checks that are associated with the current +// AWS account. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -3310,32 +3278,13 @@ func (c *Route53) ListHostedZonesRequest(input *ListHostedZonesInput) (req *requ // ListHostedZones API operation for Amazon Route 53. // -// To retrieve a list of your public and private hosted zones, send a GET request -// to the /2013-04-01/hostedzone resource. The response to this request includes -// a HostedZones child element for each hosted zone created by the current AWS -// account. +// Retrieves a list of the public and private hosted zones that are associated +// with the current AWS account. The response includes a HostedZones child element +// for each hosted zone. // // Amazon Route 53 returns a maximum of 100 items in each response. If you have // a lot of hosted zones, you can use the maxitems parameter to list them in -// groups of up to 100. The response includes four values that help navigate -// from one group of maxitems hosted zones to the next: -// -// * MaxItems is the value specified for the maxitems parameter in the request -// that produced the current response. -// -// * If the value of IsTruncated in the response is true, there are more -// hosted zones associated with the current AWS account. -// -// * NextMarker is the hosted zone ID of the next hosted zone that is associated -// with the current AWS account. If you want to list more hosted zones, make -// another call to ListHostedZones, and specify the value of the NextMarker -// element in the marker parameter. -// -// If IsTruncated is false, the NextMarker element is omitted from the response. -// -// * If you're making the second or subsequent call to ListHostedZones, the -// Marker element matches the value that you specified in the marker parameter -// in the previous request. +// groups of up to 100. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -3471,25 +3420,24 @@ func (c *Route53) ListHostedZonesByNameRequest(input *ListHostedZonesByNameInput // ListHostedZonesByName API operation for Amazon Route 53. // -// Retrieves a list of your hosted zones in lexicographic order. Send a GET -// request to the /2013-04-01/hostedzonesbyname resource. The response includes -// a HostedZones child element for each hosted zone created by the current AWS -// account. +// Retrieves a list of your hosted zones in lexicographic order. The response +// includes a HostedZones child element for each hosted zone created by the +// current AWS account. // // ListHostedZonesByName sorts hosted zones by name with the labels reversed. // For example: // -// * com.example.www. +// com.example.www. // // Note the trailing dot, which can change the sort order in some circumstances. // // If the domain name includes escape characters or Punycode, ListHostedZonesByName // alphabetizes the domain name using the escaped or Punycoded value, which // is the format that Amazon Route 53 saves in its database. For example, to -// create a hosted zone for example.com, specify ex\344mple.com for the domain -// name. ListHostedZonesByName alphabetizes it as: +// create a hosted zone for exämple.com, you specify ex\344mple.com for the +// domain name. ListHostedZonesByName alphabetizes it as: // -// * com.ex\344mple. +// com.ex\344mple. // // The labels are reversed and alphabetized using the escaped value. For more // information about valid domain name formats, including internationalized @@ -3781,16 +3729,8 @@ func (c *Route53) ListReusableDelegationSetsRequest(input *ListReusableDelegatio // ListReusableDelegationSets API operation for Amazon Route 53. // -// To retrieve a list of your reusable delegation sets, send a GET request to -// the /2013-04-01/delegationset resource. The response to this request includes -// a DelegationSets element with zero, one, or multiple DelegationSet child -// elements. By default, the list of delegation sets is displayed on a single -// page. You can control the length of the page that is displayed by using the -// MaxItems parameter. You can use the Marker parameter to control the delegation -// set that the list begins with. -// -// Amazon Route 53 returns a maximum of 100 items. If you set MaxItems to a -// value greater than 100, Amazon Route 53 returns only the first 100. +// Retrieves a list of the reusable delegation sets that are associated with +// the current AWS account. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4073,39 +4013,8 @@ func (c *Route53) ListTrafficPoliciesRequest(input *ListTrafficPoliciesInput) (r // ListTrafficPolicies API operation for Amazon Route 53. // // Gets information about the latest version for every traffic policy that is -// associated with the current AWS account. Send a GET request to the /Amazon -// Route 53 API version/trafficpolicy resource. -// -// Amazon Route 53 returns a maximum of 100 items in each response. If you have -// a lot of traffic policies, you can use the maxitems parameter to list them -// in groups of up to 100. -// -// The response includes three values that help you navigate from one group -// of maxitems traffic policies to the next: -// -// * IsTruncated -// -// If the value of IsTruncated in the response is true, there are more traffic -// policies associated with the current AWS account. -// -// If IsTruncated is false, this response includes the last traffic policy that -// is associated with the current account. -// -// * TrafficPolicyIdMarker -// -// If IsTruncated is true, TrafficPolicyIdMarker is the ID of the first traffic -// policy in the next group of MaxItems traffic policies. If you want to -// list more traffic policies, make another call to ListTrafficPolicies, -// and specify the value of the TrafficPolicyIdMarker element from the response -// in the TrafficPolicyIdMarker request parameter. -// -// If IsTruncated is false, the TrafficPolicyIdMarker element is omitted from -// the response. -// -// * MaxItems -// -// The value that you specified for the MaxItems parameter in the request that -// produced the current response. +// associated with the current AWS account. Policies are listed in the order +// in which they were created. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4193,39 +4102,10 @@ func (c *Route53) ListTrafficPolicyInstancesRequest(input *ListTrafficPolicyInst // in the traffic policy definition. For more information, see the State response // element. // -// Send a GET request to the /Amazon Route 53 API version/trafficpolicyinstance -// resource. -// // Amazon Route 53 returns a maximum of 100 items in each response. If you have // a lot of traffic policy instances, you can use the MaxItems parameter to // list them in groups of up to 100. // -// The response includes five values that help you navigate from one group of -// MaxItems traffic policy instances to the next: -// -// * IsTruncated -// -// If the value of IsTruncated in the response is true, there are more traffic -// policy instances associated with the current AWS account. -// -// If IsTruncated is false, this response includes the last traffic policy instance -// that is associated with the current account. -// -// * MaxItems -// -// The value that you specified for the MaxItems parameter in the request that -// produced the current response. -// -// * HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker -// -// If IsTruncated is true, these three values in the response represent the -// first traffic policy instance in the next group of MaxItems traffic policy -// instances. To list more traffic policy instances, make another call to -// ListTrafficPolicyInstances, and specify these values in the corresponding -// request parameters. -// -// If IsTruncated is false, all three elements are omitted from the response. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -4310,44 +4190,15 @@ func (c *Route53) ListTrafficPolicyInstancesByHostedZoneRequest(input *ListTraff // Gets information about the traffic policy instances that you created in a // specified hosted zone. // -// After you submit an UpdateTrafficPolicyInstance request, there's a brief -// delay while Amazon Route 53 creates the resource record sets that are specified -// in the traffic policy definition. For more information, see the State response -// element. -// -// Send a GET request to the /Amazon Route 53 API version/trafficpolicyinstance -// resource and include the ID of the hosted zone. +// After you submit a CreateTrafficPolicyInstance or an UpdateTrafficPolicyInstance +// request, there's a brief delay while Amazon Route 53 creates the resource +// record sets that are specified in the traffic policy definition. For more +// information, see the State response element. // // Amazon Route 53 returns a maximum of 100 items in each response. If you have // a lot of traffic policy instances, you can use the MaxItems parameter to // list them in groups of up to 100. // -// The response includes four values that help you navigate from one group of -// MaxItems traffic policy instances to the next: -// -// * IsTruncated -// -// If the value of IsTruncated in the response is true, there are more traffic -// policy instances associated with the current AWS account. -// -// * If IsTruncated is false, this response includes the last traffic policy -// instance that is associated with the current account. -// -// * MaxItems -// -// * The value that you specified for the MaxItems parameter in the request -// that produced the current response. -// -// * TrafficPolicyInstanceNameMarker and TrafficPolicyInstanceTypeMarker -// -// * If IsTruncated is true, these two values in the response represent the -// first traffic policy instance in the next group of MaxItems traffic policy -// instances. To list more traffic policy instances, make another call to -// ListTrafficPolicyInstancesByHostedZone, and specify these values in the -// corresponding request parameters. -// -// * If IsTruncated is false, all three elements are omitted from the response. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -4440,38 +4291,10 @@ func (c *Route53) ListTrafficPolicyInstancesByPolicyRequest(input *ListTrafficPo // record sets that are specified in the traffic policy definition. For more // information, see the State response element. // -// Send a GET request to the /Route 53 API version/trafficpolicyinstance resource -// and include the ID and version of the traffic policy. -// // Amazon Route 53 returns a maximum of 100 items in each response. If you have // a lot of traffic policy instances, you can use the MaxItems parameter to // list them in groups of up to 100. // -// The response includes five values that help you navigate from one group of -// MaxItems traffic policy instances to the next: -// -// * IsTruncated -// -// If the value of IsTruncated in the response is true, there are more traffic -// policy instances associated with the specified traffic policy. -// -// If IsTruncated is false, this response includes the last traffic policy instance -// that is associated with the specified traffic policy. -// -// * MaxItems -// -// The value that you specified for the MaxItems parameter in the request that -// produced the current response. -// -// * HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker -// -// If IsTruncated is true, these values in the response represent the first -// traffic policy instance in the next group of MaxItems traffic policy instances. -// To list more traffic policy instances, make another call to ListTrafficPolicyInstancesByPolicy, -// and specify these values in the corresponding request parameters. -// -// If IsTruncated is false, all three elements are omitted from the response. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -4558,38 +4381,7 @@ func (c *Route53) ListTrafficPolicyVersionsRequest(input *ListTrafficPolicyVersi // // Gets information about all of the versions for a specified traffic policy. // -// Send a GET request to the /Amazon Route 53 API version/trafficpolicy resource -// and specify the ID of the traffic policy for which you want to list versions. -// -// Amazon Route 53 returns a maximum of 100 items in each response. If you have -// a lot of traffic policies, you can use the maxitems parameter to list them -// in groups of up to 100. -// -// The response includes three values that help you navigate from one group -// of maxitems traffic policies to the next: -// -// * IsTruncated -// -// If the value of IsTruncated in the response is true, there are more traffic -// policy versions associated with the specified traffic policy. -// -// If IsTruncated is false, this response includes the last traffic policy version -// that is associated with the specified traffic policy. -// -// * TrafficPolicyVersionMarker -// -// The ID of the next traffic policy version that is associated with the current -// AWS account. If you want to list more traffic policies, make another call -// to ListTrafficPolicyVersions, and specify the value of the TrafficPolicyVersionMarker -// element in the TrafficPolicyVersionMarker request parameter. -// -// If IsTruncated is false, Amazon Route 53 omits the TrafficPolicyVersionMarker -// element from the response. -// -// * MaxItems -// -// The value that you specified for the MaxItems parameter in the request that -// produced the current response. +// Traffic policy versions are listed in numerical order by VersionNumber. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4676,23 +4468,8 @@ func (c *Route53) ListVPCAssociationAuthorizationsRequest(input *ListVPCAssociat // be associated with a specified hosted zone because you've submitted one or // more CreateVPCAssociationAuthorization requests. // -// Send a GET request to the /2013-04-01/hostedzone/hosted zone ID/authorizevpcassociation -// resource. The response to this request includes a VPCs element with a VPC -// child element for each VPC that can be associated with the hosted zone. -// -// Amazon Route 53 returns up to 50 VPCs per page. To return fewer VPCs per -// page, include the MaxResults parameter: -// -// /2013-04-01/hostedzone/hosted zone ID/authorizevpcassociation?MaxItems=VPCs -// per page -// -// If the response includes a NextToken element, there are more VPCs to list. -// To get the next page of VPCs, submit another ListVPCAssociationAuthorizations -// request, and include the value of the NextToken element from the response -// in the NextToken request parameter: -// -// /2013-04-01/hostedzone/hosted zone ID/authorizevpcassociation?MaxItems=VPCs -// per page&NextToken= +// The response includes a VPCs element with a VPC child element for each VPC +// that can be associated with the hosted zone. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4862,12 +4639,10 @@ func (c *Route53) UpdateHealthCheckRequest(input *UpdateHealthCheckInput) (req * // UpdateHealthCheck API operation for Amazon Route 53. // -// Updates an existing health check. +// Updates an existing health check. Note that some values can't be updated. // -// Send a POST request to the /2013-04-01/healthcheck/health check ID resource. -// The request body must include a document with an UpdateHealthCheckRequest -// element. For more information about updating health checks, see Creating, -// Updating, and Deleting Health Checks (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-creating-deleting.html) +// For more information about updating health checks, see Creating, Updating, +// and Deleting Health Checks (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-creating-deleting.html) // in the Amazon Route 53 Developer Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -4956,8 +4731,7 @@ func (c *Route53) UpdateHostedZoneCommentRequest(input *UpdateHostedZoneCommentI // UpdateHostedZoneComment API operation for Amazon Route 53. // -// Updates the hosted zone comment. Send a POST request to the /2013-04-01/hostedzone/hosted -// zone ID resource. +// Updates the comment for a specified hosted zone. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -5042,11 +4816,6 @@ func (c *Route53) UpdateTrafficPolicyCommentRequest(input *UpdateTrafficPolicyCo // // Updates the comment for a specified traffic policy version. // -// Send a POST request to the /2013-04-01/trafficpolicy/ resource. -// -// The request body must include a document with an UpdateTrafficPolicyCommentRequest -// element. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -5135,17 +4904,13 @@ func (c *Route53) UpdateTrafficPolicyInstanceRequest(input *UpdateTrafficPolicyI // Updates the resource record sets in a specified hosted zone that were created // based on the settings in a specified traffic policy version. // -// Send a POST request to the /2013-04-01/trafficpolicyinstance/traffic policy -// ID resource. The request body must include a document with an UpdateTrafficPolicyInstanceRequest -// element. -// // When you update a traffic policy instance, Amazon Route 53 continues to respond // to DNS queries for the root resource record set name (such as example.com) // while it replaces one group of resource record sets with another. Amazon // Route 53 performs the following operations: // // Amazon Route 53 creates a new group of resource record sets based on the -// specified traffic policy. This is true regardless of how substantial the +// specified traffic policy. This is true regardless of how significant the // differences are between the existing resource record sets and the new resource // record sets. // @@ -5358,37 +5123,10 @@ type AliasTarget struct { // DNSName is a required field DNSName *string `type:"string" required:"true"` - // Applies only to alias, weighted alias, latency alias, and failover alias - // record sets: If you set the value of EvaluateTargetHealth to true for the - // resource record set or sets in an alias, weighted alias, latency alias, or - // failover alias resource record set, and if you specify a value for HealthCheck$Id - // for every resource record set that is referenced by these alias resource - // record sets, the alias resource record sets inherit the health of the referenced - // resource record sets. - // - // In this configuration, when Amazon Route 53 receives a DNS query for an alias - // resource record set: - // - // * Amazon Route 53 looks at the resource record sets that are referenced - // by the alias resource record sets to determine which health checks they're - // using. - // - // * Amazon Route 53 checks the current status of each health check. (Amazon - // Route 53 periodically checks the health of the endpoint that is specified - // in a health check; it doesn't perform the health check when the DNS query - // arrives.) - // - // * Based on the status of the health checks, Amazon Route 53 determines - // which resource record sets are healthy. Unhealthy resource record sets - // are immediately removed from consideration. In addition, if all of the - // resource record sets that are referenced by an alias resource record set - // are unhealthy, that alias resource record set also is immediately removed - // from consideration. - // - // * Based on the configuration of the alias resource record sets (weighted - // alias or latency alias, for example) and the configuration of the resource - // record sets that they reference, Amazon Route 53 chooses a resource record - // set from the healthy resource record sets, and responds to the query. + // Applies only to alias, failover alias, geolocation alias, latency alias, + // and weighted alias resource record sets: When EvaluateTargetHealth is true, + // an alias resource record set inherits the health of the referenced AWS resource, + // such as an ELB load balancer, or the referenced resource record set. // // Note the following: // @@ -5399,7 +5137,7 @@ type AliasTarget struct { // set or a group of resource record sets (for example, a group of weighted // resource record sets), but it is not another alias resource record set, // we recommend that you associate a health check with all of the resource - // record sets in the alias target.For more information, see What Happens + // record sets in the alias target. For more information, see What Happens // When You Omit Health Checks? (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-complex-configs.html#dns-failover-complex-configs-hc-omitting) // in the Amazon Route 53 Developer Guide. // @@ -5414,19 +5152,19 @@ type AliasTarget struct { // // If the environment contains a single EC2 instance, there are no special requirements. // - // * If you specify an ELB load balancer in AliasTarget, Elastic Load Balancing - // routes queries only to the healthy EC2 instances that are registered with - // the load balancer. If no EC2 instances are healthy or if the load balancer - // itself is unhealthy, and if EvaluateTargetHealth is true for the corresponding - // alias resource record set, Amazon Route 53 routes queries to other resources. - // When you create a load balancer, you configure settings for Elastic Load - // Balancing health checks; they're not Amazon Route 53 health checks, but - // they perform a similar function. Do not create Amazon Route 53 health - // checks for the EC2 instances that you register with an ELB load balancer. + // * If you specify an ELB load balancer in AliasTarget, ELB routes queries + // only to the healthy EC2 instances that are registered with the load balancer. + // If no EC2 instances are healthy or if the load balancer itself is unhealthy, + // and if EvaluateTargetHealth is true for the corresponding alias resource + // record set, Amazon Route 53 routes queries to other resources. When you + // create a load balancer, you configure settings for ELB health checks; + // they're not Amazon Route 53 health checks, but they perform a similar + // function. Do not create Amazon Route 53 health checks for the EC2 instances + // that you register with an ELB load balancer. // // For more information, see How Health Checks Work in More Complex Amazon Route // 53 Configurations (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-complex-configs.html) - // in the Amazon Route 53 Developers Guide. + // in the Amazon Route 53 Developer Guide. // // * We recommend that you set EvaluateTargetHealth to true only when you // have enough idle capacity to handle the failure of one or more endpoints. @@ -5833,9 +5571,10 @@ type ChangeInfo struct { // Status is a required field Status *string `type:"string" required:"true" enum:"ChangeStatus"` - // The date and time the change request was submitted, in Coordinated Universal - // Time (UTC) format: YYYY-MM-DDThh:mm:ssZ. For more information, see the Wikipedia - // entry ISO 8601 (https://en.wikipedia.org/wiki/ISO_8601). + // The date and time that the change request was submitted in ISO 8601 format + // (https://en.wikipedia.org/wiki/ISO_8601) and Coordinated Universal Time (UTC). + // For example, the value 2017-03-27T17:48:16.751Z represents March 27, 2017 + // at 17:48:16.751 UTC. // // SubmittedAt is a required field SubmittedAt *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` @@ -5973,8 +5712,8 @@ type ChangeTagsForResourceInput struct { _ struct{} `locationName:"ChangeTagsForResourceRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` // A complex type that contains a list of the tags that you want to add to the - // specified health check or hosted zone and/or the tags for which you want - // to edit the Value element. + // specified health check or hosted zone and/or the tags that you want to edit + // Value for. // // You can add a maximum of 10 tags to a health check or a hosted zone. AddTags []*Tag `locationNameList:"Tag" min:"1" type:"list"` @@ -6083,7 +5822,7 @@ type CloudWatchAlarmConfiguration struct { ComparisonOperator *string `type:"string" required:"true" enum:"ComparisonOperator"` // For the metric that the CloudWatch alarm is associated with, a complex type - // that contains information about the dimensions for the metric.For information, + // that contains information about the dimensions for the metric. For information, // see Amazon CloudWatch Namespaces, Dimensions, and Metrics Reference (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html) // in the Amazon CloudWatch User Guide. Dimensions []*Dimension `locationNameList:"Dimension" type:"list"` @@ -6188,10 +5927,26 @@ func (s *CloudWatchAlarmConfiguration) SetThreshold(v float64) *CloudWatchAlarmC type CreateHealthCheckInput struct { _ struct{} `locationName:"CreateHealthCheckRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` - // A unique string that identifies the request and that allows failed CreateHealthCheck - // requests to be retried without the risk of executing the operation twice. - // You must use a unique CallerReference string every time you create a health - // check. + // A unique string that identifies the request and that allows you to retry + // a failed CreateHealthCheck request without the risk of creating two identical + // health checks: + // + // * If you send a CreateHealthCheck request with the same CallerReference + // and settings as a previous request, and if the health check doesn't exist, + // Amazon Route 53 creates the health check. If the health check does exist, + // Amazon Route 53 returns the settings for the existing health check. + // + // * If you send a CreateHealthCheck request with the same CallerReference + // as a deleted health check, regardless of the settings, Amazon Route 53 + // returns a HealthCheckAlreadyExists error. + // + // * If you send a CreateHealthCheck request with the same CallerReference + // as an existing health check but with different settings, Amazon Route + // 53 returns a HealthCheckAlreadyExists error. + // + // * If you send a CreateHealthCheck request with a unique CallerReference + // but settings identical to an existing health check, Amazon Route 53 creates + // the health check. // // CallerReference is a required field CallerReference *string `min:"1" type:"string" required:"true"` @@ -6286,15 +6041,16 @@ func (s *CreateHealthCheckOutput) SetLocation(v string) *CreateHealthCheckOutput return s } -// A complex type containing the hosted zone request information. +// A complex type that contains information about the request to create a hosted +// zone. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateHostedZoneRequest type CreateHostedZoneInput struct { _ struct{} `locationName:"CreateHostedZoneRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` // A unique string that identifies the request and that allows failed CreateHostedZone // requests to be retried without the risk of executing the operation twice. - // You must use a unique CallerReference string every time you create a hosted - // zone. CallerReference can be any unique string, for example, a date/time + // You must use a unique CallerReference string every time you submit a CreateHostedZone + // request. CallerReference can be any unique string, for example, a date/time // stamp. // // CallerReference is a required field @@ -6304,17 +6060,16 @@ type CreateHostedZoneInput struct { // the ID that Amazon Route 53 assigned to the reusable delegation set when // you created it. For more information about reusable delegation sets, see // CreateReusableDelegationSet. - // - // TypeString - // - // DefaultNone - // - // ParentCreatedHostedZoneRequest DelegationSetId *string `type:"string"` - // (Optional) A complex type that contains an optional comment about your hosted - // zone. If you don't want to specify a comment, omit both the HostedZoneConfig - // and Comment elements. + // (Optional) A complex type that contains the following optional values: + // + // * For public and private hosted zones, an optional comment + // + // * For private hosted zones, an optional PrivateZone element + // + // If you don't specify a comment or the PrivateZone element, omit HostedZoneConfig + // and the other elements. HostedZoneConfig *HostedZoneConfig `type:"structure"` // The name of the domain. For resource record types that include a domain name, @@ -6326,14 +6081,17 @@ type CreateHostedZoneInput struct { // If you're creating a public hosted zone, this is the name you have registered // with your DNS registrar. If your domain name is registered with a registrar // other than Amazon Route 53, change the name servers for your domain to the - // set of NameServers that CreateHostedZone returns in the DelegationSet element. + // set of NameServers that CreateHostedZone returns in DelegationSet. // // Name is a required field Name *string `type:"string" required:"true"` - // The VPC that you want your hosted zone to be associated with. By providing - // this parameter, your newly created hosted can't be resolved anywhere other - // than the given VPC. + // (Private hosted zones only) A complex type that contains information about + // the Amazon VPC that you're associating with this hosted zone. + // + // You can specify only one Amazon VPC when you create a private hosted zone. + // To associate additional Amazon VPCs with the hosted zone, use AssociateVPCWithHostedZone + // after you create a hosted zone. VPC *VPC `type:"structure"` } @@ -6406,7 +6164,7 @@ func (s *CreateHostedZoneInput) SetVPC(v *VPC) *CreateHostedZoneInput { type CreateHostedZoneOutput struct { _ struct{} `type:"structure"` - // A complex type that describes the changes made to your hosted zone. + // A complex type that contains information about the CreateHostedZone request. // // ChangeInfo is a required field ChangeInfo *ChangeInfo `type:"structure" required:"true"` @@ -6816,8 +6574,8 @@ func (s *CreateTrafficPolicyOutput) SetTrafficPolicy(v *TrafficPolicy) *CreateTr return s } -// A complex type that contains information about the traffic policy for which -// you want to create a new version. +// A complex type that contains information about the traffic policy that you +// want to create a new version for. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateTrafficPolicyVersionRequest type CreateTrafficPolicyVersionInput struct { _ struct{} `locationName:"CreateTrafficPolicyVersionRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` @@ -7028,23 +6786,21 @@ func (s *CreateVPCAssociationAuthorizationOutput) SetVPC(v *VPC) *CreateVPCAssoc return s } -// A complex type that describes the name servers for this hosted zone. +// A complex type that lists the name servers in a delegation set, as well as +// the CallerReference and the ID for the delegation set. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DelegationSet type DelegationSet struct { _ struct{} `type:"structure"` - // A unique string that identifies the request, and that allows you to retry - // failed CreateReusableDelegationSet requests without the risk of executing - // the operation twice. You must use a unique CallerReference string every time - // you submit a CreateReusableDelegationSet request. CallerReference can be - // any unique string, for example, a date/time stamp. + // The value that you specified for CallerReference when you created the reusable + // delegation set. CallerReference *string `min:"1" type:"string"` // The ID that Amazon Route 53 assigns to a reusable delegation set. Id *string `type:"string"` // A complex type that contains a list of the authoritative name servers for - // the hosted zone. + // a hosted zone or for a reusable delegation set. // // NameServers is a required field NameServers []*string `locationNameList:"NameServer" min:"1" type:"list" required:"true"` @@ -7078,8 +6834,7 @@ func (s *DelegationSet) SetNameServers(v []*string) *DelegationSet { return s } -// This action deletes a health check. Send a DELETE request to the /2013-04-01/DeleteHealthCheckRequest -// resource. +// This action deletes a health check. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteHealthCheckRequest type DeleteHealthCheckInput struct { _ struct{} `type:"structure"` @@ -7135,8 +6890,7 @@ func (s DeleteHealthCheckOutput) GoString() string { return s.String() } -// A complex type that contains information about the hosted zone that you want -// to delete. +// A request to delete a hosted zone. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteHostedZoneRequest type DeleteHostedZoneInput struct { _ struct{} `type:"structure"` @@ -7176,13 +6930,13 @@ func (s *DeleteHostedZoneInput) SetId(v string) *DeleteHostedZoneInput { return s } -// A complex type containing the response information for the request. +// A complex type that contains the response to a DeleteHostedZone request. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteHostedZoneResponse type DeleteHostedZoneOutput struct { _ struct{} `type:"structure"` // A complex type that contains the ID, the status, and the date and time of - // your delete request. + // a request to delete a hosted zone. // // ChangeInfo is a required field ChangeInfo *ChangeInfo `type:"structure" required:"true"` @@ -7204,12 +6958,12 @@ func (s *DeleteHostedZoneOutput) SetChangeInfo(v *ChangeInfo) *DeleteHostedZoneO return s } -// A complex type containing the information for the delete request. +// A request to delete a reusable delegation set. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteReusableDelegationSetRequest type DeleteReusableDelegationSetInput struct { _ struct{} `type:"structure"` - // The ID of the reusable delegation set you want to delete. + // The ID of the reusable delegation set that you want to delete. // // Id is a required field Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` @@ -7320,8 +7074,7 @@ func (s *DeleteTrafficPolicyInput) SetVersion(v int64) *DeleteTrafficPolicyInput return s } -// A complex type that contains information about the traffic policy instance -// that you want to delete. +// A request to delete a specified traffic policy instance. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteTrafficPolicyInstanceRequest type DeleteTrafficPolicyInstanceInput struct { _ struct{} `type:"structure"` @@ -7870,7 +7623,8 @@ func (s *GetCheckerIpRangesOutput) SetCheckerIpRanges(v []*string) *GetCheckerIp return s } -// A complex type that contains information about the request to get a geo location. +// A request for information about whether a specified geographic location is +// supported for Amazon Route 53 geolocation resource record sets. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetGeoLocationRequest type GetGeoLocationInput struct { _ struct{} `type:"structure"` @@ -7979,8 +7733,8 @@ func (s *GetGeoLocationOutput) SetGeoLocationDetails(v *GeoLocationDetails) *Get return s } -// To retrieve a count of all your health checks, send a GET request to the -// /2013-04-01/healthcheckcount resource. +// A request for the number of health checks that are associated with the current +// AWS account. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckCountRequest type GetHealthCheckCountInput struct { _ struct{} `type:"structure"` @@ -7996,7 +7750,7 @@ func (s GetHealthCheckCountInput) GoString() string { return s.String() } -// A complex type that contains the response to a healthcheckcount request. +// A complex type that contains the response to a GetHealthCheckCount request. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckCountResponse type GetHealthCheckCountOutput struct { _ struct{} `type:"structure"` @@ -8023,15 +7777,7 @@ func (s *GetHealthCheckCountOutput) SetHealthCheckCount(v int64) *GetHealthCheck return s } -// This action gets information about a specified health check. -// -// Send a GET request to the /Amazon Route 53 API version/gethealthcheckrequest -// resource. -// -// For information about getting information about a health check using the -// Amazon Route 53 console, see Amazon Route 53 Health Checks and DNS Failover -// (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html) -// in the Amazon Route 53 Developer Guide. +// A request to get information about a specified health check. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckRequest type GetHealthCheckInput struct { _ struct{} `type:"structure"` @@ -8074,15 +7820,7 @@ func (s *GetHealthCheckInput) SetHealthCheckId(v string) *GetHealthCheckInput { return s } -// This action gets the reason that a specified health check failed most recently. -// -// To get the reason for the last failure of a health check, send a GET request -// to the /2013-04-01/healthcheck/health check ID/lastfailurereason resource. -// -// For information about viewing the last failure reason for a health check -// using the Amazon Route 53 console, see Viewing Health Check Status and the -// Reason for Health Check Failures (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-monitor-view-status.html) -// in the Amazon Route 53 Developer Guide. +// A request for the reason that a health check failed most recently. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckLastFailureReasonRequest type GetHealthCheckLastFailureReasonInput struct { _ struct{} `type:"structure"` @@ -8181,13 +7919,12 @@ func (s *GetHealthCheckOutput) SetHealthCheck(v *HealthCheck) *GetHealthCheckOut return s } -// A complex type that contains information about the request to get health -// check status for a health check. +// A request to get the status for a health check. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckStatusRequest type GetHealthCheckStatusInput struct { _ struct{} `type:"structure"` - // The ID for the health check for which you want the current status. When you + // The ID for the health check that you want the current status for. When you // created the health check, CreateHealthCheck returned the ID in the response, // in the HealthCheckId element. // @@ -8256,8 +7993,8 @@ func (s *GetHealthCheckStatusOutput) SetHealthCheckObservations(v []*HealthCheck return s } -// To retrieve a count of all your hosted zones, send a GET request to the /2013-04-01/hostedzonecount -// resource. +// A request to retrieve a count of all the hosted zones that are associated +// with the current AWS account. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneCountRequest type GetHostedZoneCountInput struct { _ struct{} `type:"structure"` @@ -8273,13 +8010,13 @@ func (s GetHostedZoneCountInput) GoString() string { return s.String() } -// A complex type that contains the response to a hostedzonecount request. +// A complex type that contains the response to a GetHostedZoneCount request. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneCountResponse type GetHostedZoneCountOutput struct { _ struct{} `type:"structure"` - // The total number of public and private hosted zones associated with the current - // AWS account. + // The total number of public and private hosted zones that are associated with + // the current AWS account. // // HostedZoneCount is a required field HostedZoneCount *int64 `type:"long" required:"true"` @@ -8301,13 +8038,12 @@ func (s *GetHostedZoneCountOutput) SetHostedZoneCount(v int64) *GetHostedZoneCou return s } -// The input for a GetHostedZone request. +// A request to get information about a specified hosted zone. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneRequest type GetHostedZoneInput struct { _ struct{} `type:"structure"` - // The ID of the hosted zone for which you want to get a list of the name servers - // in the delegation set. + // The ID of the hosted zone that you want to get information about. // // Id is a required field Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` @@ -8342,21 +8078,23 @@ func (s *GetHostedZoneInput) SetId(v string) *GetHostedZoneInput { return s } -// A complex type containing the response information for the hosted zone. +// A complex type that contain the response to a GetHostedZone request. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneResponse type GetHostedZoneOutput struct { _ struct{} `type:"structure"` - // A complex type that describes the name servers for this hosted zone. + // A complex type that lists the Amazon Route 53 name servers for the specified + // hosted zone. DelegationSet *DelegationSet `type:"structure"` - // A complex type that contains general information about the hosted zone. + // A complex type that contains general information about the specified hosted + // zone. // // HostedZone is a required field HostedZone *HostedZone `type:"structure" required:"true"` - // A complex type that contains information about VPCs associated with the specified - // hosted zone. + // A complex type that contains information about the VPCs that are associated + // with the specified hosted zone. VPCs []*VPC `locationNameList:"VPC" min:"1" type:"list"` } @@ -8388,13 +8126,13 @@ func (s *GetHostedZoneOutput) SetVPCs(v []*VPC) *GetHostedZoneOutput { return s } -// The input for a GetReusableDelegationSet request. +// A request to get information about a specified reusable delegation set. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetReusableDelegationSetRequest type GetReusableDelegationSetInput struct { _ struct{} `type:"structure"` - // The ID of the reusable delegation set for which you want to get a list of - // the name server. + // The ID of the reusable delegation set that you want to get a list of name + // servers for. // // Id is a required field Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` @@ -8457,9 +8195,7 @@ func (s *GetReusableDelegationSetOutput) SetDelegationSet(v *DelegationSet) *Get return s } -// Gets information about a specific traffic policy version. To get the information, -// send a GET request to the /2013-04-01/trafficpolicy resource, and specify -// the ID and the version of the traffic policy. +// Gets information about a specific traffic policy version. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicyRequest type GetTrafficPolicyInput struct { _ struct{} `type:"structure"` @@ -8567,9 +8303,6 @@ func (s *GetTrafficPolicyInstanceCountOutput) SetTrafficPolicyInstanceCount(v in } // Gets information about a specified traffic policy instance. -// -// To get information about a traffic policy instance, send a GET request to -// the /Amazon Route 53 API version/trafficpolicyinstance/Id resource. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicyInstanceRequest type GetTrafficPolicyInstanceInput struct { _ struct{} `type:"structure"` @@ -8909,10 +8642,10 @@ type HealthCheckConfig struct { // // * Unhealthy: Amazon Route 53 considers the health check to be unhealthy. // - // * LastKnownStatus: Amazon Route 53uses the status of the health check - // from the last time CloudWatch had sufficient data to determine the alarm - // state. For new health checks that have no last known status, the default - // status for the health check is healthy. + // * LastKnownStatus: Amazon Route 53 uses the status of the health check + // from the last time that CloudWatch had sufficient data to determine the + // alarm state. For new health checks that have no last known status, the + // default status for the health check is healthy. InsufficientDataHealthStatus *string `type:"string" enum:"InsufficientDataHealthStatus"` // Specify whether you want Amazon Route 53 to invert the status of a health @@ -9010,8 +8743,9 @@ type HealthCheckConfig struct { // Route 53 health checkers consider to be healthy and compares that number // with the value of HealthThreshold. // - // For more information about how Amazon Route 53 determines whether an endpoint - // is healthy, see the introduction to this topic. + // For more information, see How Amazon Route 53 Determines Whether an Endpoint + // Is Healthy (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-determining-health-of-endpoints.html) + // in the Amazon Route 53 Developer Guide. // // Type is a required field Type *string `type:"string" required:"true" enum:"HealthCheckType"` @@ -9311,15 +9045,8 @@ func (s *HostedZoneConfig) SetPrivateZone(v bool) *HostedZoneConfig { return s } -// To get a list of geographic locations that Amazon Route 53 supports for geolocation, -// send a GET request to the /Amazon Route 53 API version/geolocations resource. -// The response to this request includes a GeoLocationDetails element for each -// location that Amazon Route 53 supports. -// -// Countries are listed first, and continents are listed last. If Amazon Route -// 53 supports subdivisions for a country (for example, states or provinces), -// the subdivisions for that country are listed in alphabetical order immediately -// after the corresponding country. +// A request to get a list of geographic locations that Amazon Route 53 supports +// for geolocation resource record sets. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListGeoLocationsRequest type ListGeoLocationsInput struct { _ struct{} `type:"structure"` @@ -9441,17 +9168,17 @@ type ListGeoLocationsOutput struct { // If IsTruncated is true, you can make a follow-up request to display more // locations. Enter the value of NextContinentCode in the StartContinentCode - // parameter in another GETListGeoLocations request. + // parameter in another ListGeoLocations request. NextContinentCode *string `min:"2" type:"string"` // If IsTruncated is true, you can make a follow-up request to display more // locations. Enter the value of NextCountryCode in the StartCountryCode parameter - // in another GETListGeoLocations request. + // in another ListGeoLocations request. NextCountryCode *string `min:"1" type:"string"` // If IsTruncated is true, you can make a follow-up request to display more // locations. Enter the value of NextSubdivisionCode in the StartSubdivisionCode - // parameter in another GETListGeoLocations request. + // parameter in another ListGeoLocations request. NextSubdivisionCode *string `min:"1" type:"string"` } @@ -9501,41 +9228,27 @@ func (s *ListGeoLocationsOutput) SetNextSubdivisionCode(v string) *ListGeoLocati return s } -// To retrieve a list of your health checks, send a GET request to the /2013-04-01/healthcheck -// resource. The response to this request includes a HealthChecks element with -// zero or more HealthCheck child elements. By default, the list of health checks -// is displayed on a single page. You can control the length of the page that -// is displayed by using the MaxItems parameter. You can use the Marker parameter -// to control the health check that the list begins with. -// -// Amazon Route 53 returns a maximum of 100 items. If you set MaxItems to a -// value greater than 100, Amazon Route 53 returns only the first 100. +// A request to retrieve a list of the health checks that are associated with +// the current AWS account. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHealthChecksRequest type ListHealthChecksInput struct { _ struct{} `type:"structure"` - // If the response to a ListHealthChecks is more than one page, marker is the - // health check ID for the first health check on the next page of results. For - // more information, see ListHealthChecksResponse$MaxItems. + // If the value of IsTruncated in the previous response was true, you have more + // health checks. To get another group, submit another ListHealthChecks request. + // + // For the value of marker, specify the value of NextMarker from the previous + // response, which is the ID of the first health check that Amazon Route 53 + // will return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more health checks to get. Marker *string `location:"querystring" locationName:"marker" type:"string"` - // The maximum number of HealthCheck elements you want ListHealthChecks to return - // on each page of the response body. If the AWS account includes more HealthCheck - // elements than the value of maxitems, the response is broken into pages. Each - // page contains the number of HealthCheck elements specified by maxitems. - // - // For example, suppose you specify 10 for maxitems and the current AWS account - // has 51 health checks. In the response, ListHealthChecks sets ListHealthChecksResponse$IsTruncated - // to true and includes the ListHealthChecksResponse$NextMarker element. To - // access the second and subsequent pages, you resend the GETListHealthChecks - // request, add the ListHealthChecksResponse$Marker parameter to the request, - // and specify the value of the ListHealthChecksResponse$NextMarker element - // from the previous response. On the last (sixth) page of the response, which - // contains only one HealthCheck element: - // - // * The value of ListHealthChecksResponse$IsTruncated is false. - // - // * ListHealthChecksResponse$NextMarker is omitted. + // The maximum number of health checks that you want ListHealthChecks to return + // in response to the current request. Amazon Route 53 returns a maximum of + // 100 items. If you set MaxItems to a value greater than 100, Amazon Route + // 53 returns only the first 100 health checks. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` } @@ -9573,11 +9286,9 @@ type ListHealthChecksOutput struct { HealthChecks []*HealthCheck `locationNameList:"HealthCheck" type:"list" required:"true"` // A flag that indicates whether there are more health checks to be listed. - // If the response was truncated, you can get the next group of maxitems health - // checks by calling ListHealthChecks again and specifying the value of the - // NextMarker element in the marker parameter. - // - // Valid Values: true | false + // If the response was truncated, you can get the next group of health checks + // by submitting another ListHealthChecks request and specifying the value of + // NextMarker in the marker parameter. // // IsTruncated is a required field IsTruncated *bool `type:"boolean" required:"true"` @@ -9595,8 +9306,8 @@ type ListHealthChecksOutput struct { MaxItems *string `type:"string" required:"true"` // If IsTruncated is true, the value of NextMarker identifies the first health - // check in the next group of maxitems health checks. Call ListHealthChecks - // again and specify the value of NextMarker in the marker parameter. + // check that Amazon Route 53 returns if you submit another ListHealthChecks + // request and specify the value of NextMarker in the marker parameter. NextMarker *string `type:"string"` } @@ -9640,52 +9351,8 @@ func (s *ListHealthChecksOutput) SetNextMarker(v string) *ListHealthChecksOutput return s } -// To retrieve a list of your public and private hosted zones in ASCII order -// by domain name, send a GET request to the /Amazon Route 53 API version/hostedzonesbyname -// resource. The response to this request includes a HostedZone child element -// for each hosted zone that was created by the current AWS account. ListHostedZonesByName -// sorts hosted zones by name with the labels reversed, for example: -// -// com.example.www. -// -// Note the trailing dot, which can change the sort order in some circumstances. -// -// If the domain name includes escape characters or Punycode, ListHostedZonesByName -// alphabetizes the domain name using the escaped or Punycoded value, which -// is the format that Amazon Route 53 saves in its database. For example, to -// create a hosted zone for exämple.com, you specify ex\344mple.com for the -// domain name. ListHostedZonesByName alphabetizes it as: com.ex\344mple. The -// labels are reversed, and it's alphabetized using the escaped value. For more -// information about valid domain name formats, including internationalized -// domain names, see DNS Domain Name Format (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DomainNameFormat.html) -// in the Amazon Route 53 Developer Guide. -// -// Amazon Route 53 returns up to 100 items in each response. If you have a lot -// of hosted zones, you can use the MaxItems parameter to list them in groups -// of up to 100. The response includes values that help you navigate from one -// group of MaxItems hosted zones to the next: -// -// * The DNSName and HostedZoneId elements in the response contain the values, -// if any, that you specified for the dnsname and hostedzoneid parameters -// in the request that produced the current response. -// -// * The MaxItems element in the response contains the value, if any, that -// you specified for the maxitems parameter in the request that produced -// the current response. -// -// * If the value of IsTruncated in the response is true, there are more -// hosted zones associated with the current Amazon Route 53 account. -// -// If IsTruncated is false, this response includes the last hosted zone that -// is associated with the current account. The NextDNSName element and NextHostedZoneId -// elements are omitted from the response. -// -// * The NextDNSName and NextHostedZoneId elements in the response contain -// the domain name and the hosted zone ID of the next hosted zone that is -// associated with the current AWS account. If you want to list more hosted -// zones, make another call to ListHostedZonesByName, and specify the value -// of NextDNSName and NextHostedZoneId in the dnsname and hostedzoneid parameters, -// respectively. +// Retrieves a list of the public and private hosted zones that are associated +// with the current AWS account in ASCII order by domain name. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHostedZonesByNameRequest type ListHostedZonesByNameInput struct { _ struct{} `type:"structure"` @@ -9848,35 +9515,8 @@ func (s *ListHostedZonesByNameOutput) SetNextHostedZoneId(v string) *ListHostedZ return s } -// To retrieve a list of your public and private hosted zones, send a GET request -// to the /2013-04-01/hostedzone resource. The response to this request includes -// a HostedZone child element for each hosted zone that was created by the current -// AWS account. -// -// Amazon Route 53 returns a maximum of 100 items in each response. If you have -// a lot of hosted zones, you can use the maxitems parameter to list them in -// groups of up to 100. The response includes four values that help you navigate -// from one group of maxitems hosted zones to the next: -// -// * MaxItems is the value that you specified for the maxitems parameter -// in the request that produced the current response. -// -// * If the value of IsTruncated in the response is true, there are more -// hosted zones associated with the current AWS account. -// -// If IsTruncated is false, this response includes the last hosted zone that -// is associated with the current account. -// -// * NextMarker is the hosted zone ID of the next hosted zone that is associated -// with the current AWS account. If you want to list more hosted zones, make -// another call to ListHostedZones, and specify the value of the NextMarker -// element in the marker parameter. -// -// If IsTruncated is false, the NextMarker element is omitted from the response. -// -// * If you're making the second or subsequent call to ListHostedZones, the -// Marker element matches the value that you specified in the marker parameter -// in the previous request. +// A request to retrieve a list of the public and private hosted zones that +// are associated with the current AWS account. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHostedZonesRequest type ListHostedZonesInput struct { _ struct{} `type:"structure"` @@ -9886,20 +9526,22 @@ type ListHostedZonesInput struct { // the ID of that reusable delegation set. DelegationSetId *string `location:"querystring" locationName:"delegationsetid" type:"string"` - // (Optional) If you have more hosted zones than the value of maxitems, ListHostedZones - // returns only the first maxitems hosted zones. To get the next group of maxitems - // hosted zones, submit another request to ListHostedZones. For the value of - // marker, specify the value of the NextMarker element that was returned in - // the previous response. + // If the value of IsTruncated in the previous response was true, you have more + // hosted zones. To get more hosted zones, submit another ListHostedZones request. // - // Hosted zones are listed in the order in which they were created. + // For the value of marker, specify the value of NextMarker from the previous + // response, which is the ID of the first hosted zone that Amazon Route 53 will + // return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more hosted zones to get. Marker *string `location:"querystring" locationName:"marker" type:"string"` - // (Optional) The maximum number of hosted zones to be included in the response - // body for this request. If you have more than maxitems hosted zones, the value - // of the IsTruncated element in the response is true, and the value of the - // NextMarker element is the hosted zone ID of the first hosted zone in the - // next group of maxitems hosted zones. + // (Optional) The maximum number of hosted zones that you want Amazon Route + // 53 to return. If you have more than maxitems hosted zones, the value of IsTruncated + // in the response is true, and the value of NextMarker is the hosted zone ID + // of the first hosted zone that Amazon Route 53 will return if you submit another + // request. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` } @@ -9941,9 +9583,9 @@ type ListHostedZonesOutput struct { HostedZones []*HostedZone `locationNameList:"HostedZone" type:"list" required:"true"` // A flag indicating whether there are more hosted zones to be listed. If the - // response was truncated, you can get the next group of maxitems hosted zones - // by calling ListHostedZones again and specifying the value of the NextMarker - // element in the marker parameter. + // response was truncated, you can get more hosted zones by submitting another + // ListHostedZones request and specifying the value of NextMarker in the marker + // parameter. // // IsTruncated is a required field IsTruncated *bool `type:"boolean" required:"true"` @@ -9962,8 +9604,8 @@ type ListHostedZonesOutput struct { MaxItems *string `type:"string" required:"true"` // If IsTruncated is true, the value of NextMarker identifies the first hosted - // zone in the next group of maxitems hosted zones. Call ListHostedZones again - // and specify the value of NextMarker in the marker parameter. + // zone in the next group of hosted zones. Submit another ListHostedZones request, + // and specify the value of NextMarker from the response in the marker parameter. // // This element is present only if IsTruncated is true. NextMarker *string `type:"string"` @@ -10009,13 +9651,14 @@ func (s *ListHostedZonesOutput) SetNextMarker(v string) *ListHostedZonesOutput { return s } -// The input for a ListResourceRecordSets request. +// A request for the resource record sets that are associated with a specified +// hosted zone. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListResourceRecordSetsRequest type ListResourceRecordSetsInput struct { _ struct{} `type:"structure"` // The ID of the hosted zone that contains the resource record sets that you - // want to get. + // want to list. // // HostedZoneId is a required field HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` @@ -10034,8 +9677,8 @@ type ListResourceRecordSetsInput struct { // and type. StartRecordIdentifier *string `location:"querystring" locationName:"identifier" min:"1" type:"string"` - // The first name in the lexicographic ordering of domain names that you want - // the ListResourceRecordSets request to list. + // The first name in the lexicographic ordering of resource record sets that + // you want to list. StartRecordName *string `location:"querystring" locationName:"name" type:"string"` // The type of resource record set to begin the record listing from. @@ -10201,27 +9844,27 @@ func (s *ListResourceRecordSetsOutput) SetResourceRecordSets(v []*ResourceRecord return s } -// To retrieve a list of your reusable delegation sets, send a GET request to -// the /2013-04-01/delegationset resource. The response to this request includes -// a DelegationSets element with zero or more DelegationSet child elements. -// By default, the list of reusable delegation sets is displayed on a single -// page. You can control the length of the page that is displayed by using the -// MaxItems parameter. You can use the Marker parameter to control the delegation -// set that the list begins with. -// -// Amazon Route 53 returns a maximum of 100 items. If you set MaxItems to a -// value greater than 100, Amazon Route 53 returns only the first 100. +// A request to get a list of the reusable delegation sets that are associated +// with the current AWS account. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListReusableDelegationSetsRequest type ListReusableDelegationSetsInput struct { _ struct{} `type:"structure"` - // If you're making the second or subsequent call to ListReusableDelegationSets, - // the Marker element matches the value that you specified in the marker parameter - // in the previous request. + // If the value of IsTruncated in the previous response was true, you have more + // reusable delegation sets. To get another group, submit another ListReusableDelegationSets + // request. + // + // For the value of marker, specify the value of NextMarker from the previous + // response, which is the ID of the first reusable delegation set that Amazon + // Route 53 will return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more reusable delegation sets to get. Marker *string `location:"querystring" locationName:"marker" type:"string"` - // The value that you specified for the maxitems parameter in the request that - // produced the current response. + // The number of reusable delegation sets that you want Amazon Route 53 to return + // in the response to this request. If you specify a value greater than 100, + // Amazon Route 53 returns only the first 100 reusable delegation sets. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` } @@ -10260,9 +9903,7 @@ type ListReusableDelegationSetsOutput struct { DelegationSets []*DelegationSet `locationNameList:"DelegationSet" type:"list" required:"true"` // A flag that indicates whether there are more reusable delegation sets to - // be listed. If the response is truncated, you can get the next group of maxitems - // reusable delegation sets by calling ListReusableDelegationSets again and - // specifying the value of the NextMarker element in the marker parameter. + // be listed. // // IsTruncated is a required field IsTruncated *bool `type:"boolean" required:"true"` @@ -10280,10 +9921,9 @@ type ListReusableDelegationSetsOutput struct { // MaxItems is a required field MaxItems *string `type:"string" required:"true"` - // If IsTruncated is true, the value of NextMarker identifies the first reusable - // delegation set in the next group of maxitems reusable delegation sets. Call - // ListReusableDelegationSets again and specify the value of NextMarker in the - // marker parameter. + // If IsTruncated is true, the value of NextMarker identifies the next reusable + // delegation set that Amazon Route 53 will return if you submit another ListReusableDelegationSets + // request and specify the value of NextMarker in the marker parameter. NextMarker *string `type:"string"` } @@ -10510,23 +10150,21 @@ func (s *ListTagsForResourcesOutput) SetResourceTagSets(v []*ResourceTagSet) *Li type ListTrafficPoliciesInput struct { _ struct{} `type:"structure"` - // (Optional) The maximum number of traffic policies to be included in the response - // body for this request. If you have more than MaxItems traffic policies, the - // value of the IsTruncated element in the response is true, and the value of - // the TrafficPolicyIdMarker element is the ID of the first traffic policy in - // the next group of MaxItems traffic policies. + // (Optional) The maximum number of traffic policies that you want Amazon Route + // 53 to return in response to this request. If you have more than MaxItems + // traffic policies, the value of IsTruncated in the response is true, and the + // value of TrafficPolicyIdMarker is the ID of the first traffic policy that + // Amazon Route 53 will return if you submit another request. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` - // (Conditional) For your first request to ListTrafficPolicies, do not include + // (Conditional) For your first request to ListTrafficPolicies, don't include // the TrafficPolicyIdMarker parameter. // // If you have more traffic policies than the value of MaxItems, ListTrafficPolicies // returns only the first MaxItems traffic policies. To get the next group of - // MaxItems policies, submit another request to ListTrafficPolicies. For the - // value of TrafficPolicyIdMarker, specify the value of the TrafficPolicyIdMarker - // element that was returned in the previous response. - // - // Policies are listed in the order in which they were created. + // policies, submit another request to ListTrafficPolicies. For the value of + // TrafficPolicyIdMarker, specify the value of TrafficPolicyIdMarker that was + // returned in the previous response. TrafficPolicyIdMarker *string `location:"querystring" locationName:"trafficpolicyid" min:"1" type:"string"` } @@ -10571,17 +10209,15 @@ type ListTrafficPoliciesOutput struct { _ struct{} `type:"structure"` // A flag that indicates whether there are more traffic policies to be listed. - // If the response was truncated, you can get the next group of MaxItems traffic - // policies by calling ListTrafficPolicies again and specifying the value of - // the TrafficPolicyIdMarker element in the TrafficPolicyIdMarker request parameter. - // - // Valid Values: true | false + // If the response was truncated, you can get the next group of traffic policies + // by submitting another ListTrafficPolicies request and specifying the value + // of TrafficPolicyIdMarker in the TrafficPolicyIdMarker request parameter. // // IsTruncated is a required field IsTruncated *bool `type:"boolean" required:"true"` - // The value that you specified for the MaxItems parameter in the call to ListTrafficPolicies - // that produced the current response. + // The value that you specified for the MaxItems parameter in the ListTrafficPolicies + // request that produced the current response. // // MaxItems is a required field MaxItems *string `type:"string" required:"true"` @@ -10639,7 +10275,8 @@ func (s *ListTrafficPoliciesOutput) SetTrafficPolicySummaries(v []*TrafficPolicy type ListTrafficPolicyInstancesByHostedZoneInput struct { _ struct{} `type:"structure"` - // The ID of the hosted zone for which you want to list traffic policy instances. + // The ID of the hosted zone that you want to list traffic policy instances + // for. // // HostedZoneId is a required field HostedZoneId *string `location:"querystring" locationName:"id" type:"string" required:"true"` @@ -10648,33 +10285,30 @@ type ListTrafficPolicyInstancesByHostedZoneInput struct { // body for this request. If you have more than MaxItems traffic policy instances, // the value of the IsTruncated element in the response is true, and the values // of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker - // represent the first traffic policy instance in the next group of MaxItems - // traffic policy instances. + // represent the first traffic policy instance that Amazon Route 53 will return + // if you submit another request. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` - // For the first request to ListTrafficPolicyInstancesByHostedZone, omit this - // value. - // - // If the value of IsTruncated in the previous response was true, TrafficPolicyInstanceNameMarker - // is the name of the first traffic policy instance in the next group of MaxItems - // traffic policy instances. + // If the value of IsTruncated in the previous response is true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancename, + // specify the value of TrafficPolicyInstanceNameMarker from the previous response, + // which is the name of the first traffic policy instance in the next group + // of traffic policy instances. // // If the value of IsTruncated in the previous response was false, there are - // no more traffic policy instances to get for this hosted zone. - // - // If the value of IsTruncated in the previous response was false, omit this - // value. + // no more traffic policy instances to get. TrafficPolicyInstanceNameMarker *string `location:"querystring" locationName:"trafficpolicyinstancename" type:"string"` - // For the first request to ListTrafficPolicyInstancesByHostedZone, omit this - // value. - // - // If the value of IsTruncated in the previous response was true, TrafficPolicyInstanceTypeMarker - // is the DNS type of the first traffic policy instance in the next group of - // MaxItems traffic policy instances. + // If the value of IsTruncated in the previous response is true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancetype, + // specify the value of TrafficPolicyInstanceTypeMarker from the previous response, + // which is the type of the first traffic policy instance in the next group + // of traffic policy instances. // // If the value of IsTruncated in the previous response was false, there are - // no more traffic policy instances to get for this hosted zone. + // no more traffic policy instances to get. TrafficPolicyInstanceTypeMarker *string `location:"querystring" locationName:"trafficpolicyinstancetype" type:"string" enum:"RRType"` } @@ -10731,29 +10365,27 @@ type ListTrafficPolicyInstancesByHostedZoneOutput struct { _ struct{} `type:"structure"` // A flag that indicates whether there are more traffic policy instances to - // be listed. If the response was truncated, you can get the next group of MaxItems - // traffic policy instances by calling ListTrafficPolicyInstancesByHostedZone - // again and specifying the values of the HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, - // and TrafficPolicyInstanceTypeMarker elements in the corresponding request - // parameters. + // be listed. If the response was truncated, you can get the next group of traffic + // policy instances by submitting another ListTrafficPolicyInstancesByHostedZone + // request and specifying the values of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, + // and TrafficPolicyInstanceTypeMarker in the corresponding request parameters. // // IsTruncated is a required field IsTruncated *bool `type:"boolean" required:"true"` - // The value that you specified for the MaxItems parameter in the call to ListTrafficPolicyInstancesByHostedZone - // that produced the current response. + // The value that you specified for the MaxItems parameter in the ListTrafficPolicyInstancesByHostedZone + // request that produced the current response. // // MaxItems is a required field MaxItems *string `type:"string" required:"true"` // If IsTruncated is true, TrafficPolicyInstanceNameMarker is the name of the - // first traffic policy instance in the next group of MaxItems traffic policy - // instances. + // first traffic policy instance in the next group of traffic policy instances. TrafficPolicyInstanceNameMarker *string `type:"string"` // If IsTruncated is true, TrafficPolicyInstanceTypeMarker is the DNS type of // the resource record sets that are associated with the first traffic policy - // instance in the next group of MaxItems traffic policy instances. + // instance in the next group of traffic policy instances. TrafficPolicyInstanceTypeMarker *string `type:"string" enum:"RRType"` // A list that contains one TrafficPolicyInstance element for each traffic policy @@ -10809,25 +10441,24 @@ func (s *ListTrafficPolicyInstancesByHostedZoneOutput) SetTrafficPolicyInstances type ListTrafficPolicyInstancesByPolicyInput struct { _ struct{} `type:"structure"` - // For the first request to ListTrafficPolicyInstancesByPolicy, omit this value. + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstancesByPolicy request. // - // If the value of IsTruncated in the previous response was true, HostedZoneIdMarker - // is the ID of the hosted zone for the first traffic policy instance in the - // next group of MaxItems traffic policy instances. + // For the value of hostedzoneid, specify the value of HostedZoneIdMarker from + // the previous response, which is the hosted zone ID of the first traffic policy + // instance that Amazon Route 53 will return if you submit another request. // // If the value of IsTruncated in the previous response was false, there are - // no more traffic policy instances to get for this hosted zone. - // - // If the value of IsTruncated in the previous response was false, omit this - // value. + // no more traffic policy instances to get. HostedZoneIdMarker *string `location:"querystring" locationName:"hostedzoneid" type:"string"` // The maximum number of traffic policy instances to be included in the response // body for this request. If you have more than MaxItems traffic policy instances, // the value of the IsTruncated element in the response is true, and the values // of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker - // represent the first traffic policy instance in the next group of MaxItems - // traffic policy instances. + // represent the first traffic policy instance that Amazon Route 53 will return + // if you submit another request. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` // The ID of the traffic policy for which you want to list traffic policy instances. @@ -10835,27 +10466,28 @@ type ListTrafficPolicyInstancesByPolicyInput struct { // TrafficPolicyId is a required field TrafficPolicyId *string `location:"querystring" locationName:"id" min:"1" type:"string" required:"true"` - // For the first request to ListTrafficPolicyInstancesByPolicy, omit this value. + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstancesByPolicy request. // - // If the value of IsTruncated in the previous response was true, TrafficPolicyInstanceNameMarker - // is the name of the first traffic policy instance in the next group of MaxItems - // traffic policy instances. + // For the value of trafficpolicyinstancename, specify the value of TrafficPolicyInstanceNameMarker + // from the previous response, which is the name of the first traffic policy + // instance that Amazon Route 53 will return if you submit another request. // // If the value of IsTruncated in the previous response was false, there are - // no more traffic policy instances to get for this hosted zone. - // - // If the value of IsTruncated in the previous response was false, omit this - // value. + // no more traffic policy instances to get. TrafficPolicyInstanceNameMarker *string `location:"querystring" locationName:"trafficpolicyinstancename" type:"string"` - // For the first request to ListTrafficPolicyInstancesByPolicy, omit this value. + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstancesByPolicy request. // - // If the value of IsTruncated in the previous response was true, TrafficPolicyInstanceTypeMarker - // is the DNS type of the first traffic policy instance in the next group of - // MaxItems traffic policy instances. + // For the value of trafficpolicyinstancetype, specify the value of TrafficPolicyInstanceTypeMarker + // from the previous response, which is the name of the first traffic policy + // instance that Amazon Route 53 will return if you submit another request. // // If the value of IsTruncated in the previous response was false, there are - // no more traffic policy instances to get for this hosted zone. + // no more traffic policy instances to get. TrafficPolicyInstanceTypeMarker *string `location:"querystring" locationName:"trafficpolicyinstancetype" type:"string" enum:"RRType"` // The version of the traffic policy for which you want to list traffic policy @@ -10940,14 +10572,13 @@ type ListTrafficPolicyInstancesByPolicyOutput struct { _ struct{} `type:"structure"` // If IsTruncated is true, HostedZoneIdMarker is the ID of the hosted zone of - // the first traffic policy instance in the next group of MaxItems traffic policy - // instances. + // the first traffic policy instance in the next group of traffic policy instances. HostedZoneIdMarker *string `type:"string"` // A flag that indicates whether there are more traffic policy instances to - // be listed. If the response was truncated, you can get the next group of MaxItems - // traffic policy instances by calling ListTrafficPolicyInstancesByPolicy again - // and specifying the values of the HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, + // be listed. If the response was truncated, you can get the next group of traffic + // policy instances by calling ListTrafficPolicyInstancesByPolicy again and + // specifying the values of the HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, // and TrafficPolicyInstanceTypeMarker elements in the corresponding request // parameters. // @@ -11029,42 +10660,42 @@ func (s *ListTrafficPolicyInstancesByPolicyOutput) SetTrafficPolicyInstances(v [ type ListTrafficPolicyInstancesInput struct { _ struct{} `type:"structure"` - // For the first request to ListTrafficPolicyInstances, omit this value. - // // If the value of IsTruncated in the previous response was true, you have more - // traffic policy instances. To get the next group of MaxItems traffic policy - // instances, submit another ListTrafficPolicyInstances request. For the value - // of HostedZoneIdMarker, specify the value of HostedZoneIdMarker from the previous - // response, which is the hosted zone ID of the first traffic policy instance - // in the next group of MaxItems traffic policy instances. + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of HostedZoneId, specify + // the value of HostedZoneIdMarker from the previous response, which is the + // hosted zone ID of the first traffic policy instance in the next group of + // traffic policy instances. // // If the value of IsTruncated in the previous response was false, there are // no more traffic policy instances to get. HostedZoneIdMarker *string `location:"querystring" locationName:"hostedzoneid" type:"string"` - // The maximum number of traffic policy instances to be included in the response - // body for this request. If you have more than MaxItems traffic policy instances, - // the value of the IsTruncated element in the response is true, and the values - // of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker - // represent the first traffic policy instance in the next group of MaxItems - // traffic policy instances. + // The maximum number of traffic policy instances that you want Amazon Route + // 53 to return in response to a ListTrafficPolicyInstances request. If you + // have more than MaxItems traffic policy instances, the value of the IsTruncated + // element in the response is true, and the values of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, + // and TrafficPolicyInstanceTypeMarker represent the first traffic policy instance + // in the next group of MaxItems traffic policy instances. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` - // For the first request to ListTrafficPolicyInstances, omit this value. - // - // If the value of IsTruncated in the previous response was true, TrafficPolicyInstanceNameMarker - // is the name of the first traffic policy instance in the next group of MaxItems - // traffic policy instances. + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancename, + // specify the value of TrafficPolicyInstanceNameMarker from the previous response, + // which is the name of the first traffic policy instance in the next group + // of traffic policy instances. // // If the value of IsTruncated in the previous response was false, there are // no more traffic policy instances to get. TrafficPolicyInstanceNameMarker *string `location:"querystring" locationName:"trafficpolicyinstancename" type:"string"` - // For the first request to ListTrafficPolicyInstances, omit this value. - // - // If the value of IsTruncated in the previous response was true, TrafficPolicyInstanceTypeMarker - // is the DNS type of the first traffic policy instance in the next group of - // MaxItems traffic policy instances. + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancetype, + // specify the value of TrafficPolicyInstanceTypeMarker from the previous response, + // which is the type of the first traffic policy instance in the next group + // of traffic policy instances. // // If the value of IsTruncated in the previous response was false, there are // no more traffic policy instances to get. @@ -11111,16 +10742,15 @@ type ListTrafficPolicyInstancesOutput struct { _ struct{} `type:"structure"` // If IsTruncated is true, HostedZoneIdMarker is the ID of the hosted zone of - // the first traffic policy instance in the next group of MaxItems traffic policy - // instances. + // the first traffic policy instance that Amazon Route 53 will return if you + // submit another ListTrafficPolicyInstances request. HostedZoneIdMarker *string `type:"string"` // A flag that indicates whether there are more traffic policy instances to - // be listed. If the response was truncated, you can get the next group of MaxItems - // traffic policy instances by calling ListTrafficPolicyInstances again and - // specifying the values of the HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, - // and TrafficPolicyInstanceTypeMarker elements in the corresponding request - // parameters. + // be listed. If the response was truncated, you can get more traffic policy + // instances by calling ListTrafficPolicyInstances again and specifying the + // values of the HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker + // in the corresponding request parameters. // // IsTruncated is a required field IsTruncated *bool `type:"boolean" required:"true"` @@ -11132,13 +10762,14 @@ type ListTrafficPolicyInstancesOutput struct { MaxItems *string `type:"string" required:"true"` // If IsTruncated is true, TrafficPolicyInstanceNameMarker is the name of the - // first traffic policy instance in the next group of MaxItems traffic policy - // instances. + // first traffic policy instance that Amazon Route 53 will return if you submit + // another ListTrafficPolicyInstances request. TrafficPolicyInstanceNameMarker *string `type:"string"` // If IsTruncated is true, TrafficPolicyInstanceTypeMarker is the DNS type of // the resource record sets that are associated with the first traffic policy - // instance in the next group of MaxItems traffic policy instances. + // instance that Amazon Route 53 will return if you submit another ListTrafficPolicyInstances + // request. TrafficPolicyInstanceTypeMarker *string `type:"string" enum:"RRType"` // A list that contains one TrafficPolicyInstance element for each traffic policy @@ -11208,22 +10839,20 @@ type ListTrafficPolicyVersionsInput struct { // The maximum number of traffic policy versions that you want Amazon Route // 53 to include in the response body for this request. If the specified traffic - // policy has more than MaxItems versions, the value of the IsTruncated element - // in the response is true, and the value of the TrafficPolicyVersionMarker - // element is the ID of the first version in the next group of MaxItems traffic - // policy versions. + // policy has more than MaxItems versions, the value of IsTruncated in the response + // is true, and the value of the TrafficPolicyVersionMarker element is the ID + // of the first version that Amazon Route 53 will return if you submit another + // request. MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` - // For your first request to ListTrafficPolicyVersions, do not include the TrafficPolicyVersionMarker + // For your first request to ListTrafficPolicyVersions, don't include the TrafficPolicyVersionMarker // parameter. // // If you have more traffic policy versions than the value of MaxItems, ListTrafficPolicyVersions - // returns only the first group of MaxItems versions. To get the next group - // of MaxItems traffic policy versions, submit another request to ListTrafficPolicyVersions. - // For the value of TrafficPolicyVersionMarker, specify the value of the TrafficPolicyVersionMarker - // element that was returned in the previous response. - // - // Traffic policy versions are listed in sequential order. + // returns only the first group of MaxItems versions. To get more traffic policy + // versions, submit another ListTrafficPolicyVersions request. For the value + // of TrafficPolicyVersionMarker, specify the value of TrafficPolicyVersionMarker + // in the previous response. TrafficPolicyVersionMarker *string `location:"querystring" locationName:"trafficpolicyversion" type:"string"` } @@ -11277,15 +10906,15 @@ type ListTrafficPolicyVersionsOutput struct { _ struct{} `type:"structure"` // A flag that indicates whether there are more traffic policies to be listed. - // If the response was truncated, you can get the next group of maxitems traffic - // policies by calling ListTrafficPolicyVersions again and specifying the value - // of the NextMarker element in the marker parameter. + // If the response was truncated, you can get the next group of traffic policies + // by submitting another ListTrafficPolicyVersions request and specifying the + // value of NextMarker in the marker parameter. // // IsTruncated is a required field IsTruncated *bool `type:"boolean" required:"true"` - // The value that you specified for the maxitems parameter in the call to ListTrafficPolicyVersions - // that produced the current response. + // The value that you specified for the maxitems parameter in the ListTrafficPolicyVersions + // request that produced the current response. // // MaxItems is a required field MaxItems *string `type:"string" required:"true"` @@ -11297,8 +10926,8 @@ type ListTrafficPolicyVersionsOutput struct { TrafficPolicies []*TrafficPolicy `locationNameList:"TrafficPolicy" type:"list" required:"true"` // If IsTruncated is true, the value of TrafficPolicyVersionMarker identifies - // the first traffic policy in the next group of MaxItems traffic policies. - // Call ListTrafficPolicyVersions again and specify the value of TrafficPolicyVersionMarker + // the first traffic policy that Amazon Route 53 will return if you submit another + // request. Call ListTrafficPolicyVersions again and specify the value of TrafficPolicyVersionMarker // in the TrafficPolicyVersionMarker request parameter. // // This element is present only if IsTruncated is true. @@ -11354,13 +10983,14 @@ type ListVPCAssociationAuthorizationsInput struct { HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` // Optional: An integer that specifies the maximum number of VPCs that you want - // Amazon Route 53 to return. + // Amazon Route 53 to return. If you don't specify a value for MaxResults, Amazon + // Route 53 returns up to 50 VPCs per page. MaxResults *string `location:"querystring" locationName:"maxresults" type:"string"` // Optional: If a response includes a NextToken element, there are more VPCs // that can be associated with the specified hosted zone. To get the next page - // of results, submit another request, and include the value of the NextToken - // element in from the response in the NextToken parameter in another ListVPCAssociationAuthorizations + // of results, submit another request, and include the value of NextToken from + // the response in the nexttoken parameter in another ListVPCAssociationAuthorizations // request. NextToken *string `location:"querystring" locationName:"nexttoken" type:"string"` } @@ -11419,11 +11049,8 @@ type ListVPCAssociationAuthorizationsOutput struct { // When the response includes a NextToken element, there are more VPCs that // can be associated with the specified hosted zone. To get the next page of // VPCs, submit another ListVPCAssociationAuthorizations request, and include - // the value of the NextToken element from the response in the NextToken request - // parameter: - // - // /2013-04-01/hostedzone/hosted zone ID/authorizevpcassociation?MaxItems=VPCs - // per page&NextToken= + // the value of the NextToken element from the response in the nexttoken request + // parameter. NextToken *string `type:"string"` // The list of VPCs that are authorized to be associated with the specified @@ -11576,8 +11203,6 @@ type ResourceRecordSet struct { // * Amazon Route 53 Health Checks and DNS Failover (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html) // // * Configuring Failover in a Private Hosted Zone (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-private-hosted-zones.html) - // - // Valid values: PRIMARY | SECONDARY Failover *string `type:"string" enum:"ResourceRecordSetFailover"` // Geo location resource record sets only: A complex type that lets you control @@ -11703,7 +11328,7 @@ type ResourceRecordSet struct { // in the Amazon Route 53 Developer Guide. // // You can use the asterisk (*) wildcard to replace the leftmost label in a - // domain name. For example, *.example.com. Note the following: + // domain name, for example, *.example.com. Note the following: // // * The * must replace the entire label. For example, you can't specify // *prod.example.com or prod*.example.com. @@ -11724,8 +11349,8 @@ type ResourceRecordSet struct { // Name is a required field Name *string `type:"string" required:"true"` - // Latency-based resource record sets only: The Amazon EC2 Region where the - // resource that is specified in this resource record set resides. The resource + // Latency-based resource record sets only: The Amazon EC2 Region where you + // created the resource that this resource record set refers to. The resource // typically is an AWS resource, such as an EC2 instance or an ELB load balancer, // and is referred to by an IP address or a DNS domain name, depending on the // record type. @@ -11749,7 +11374,7 @@ type ResourceRecordSet struct { // // * You aren't required to create latency resource record sets for all Amazon // EC2 Regions. Amazon Route 53 will choose the region with the best latency - // from among the regions for which you create latency resource record sets. + // from among the regions that you create latency resource record sets for. // // * You can't create non-latency resource record sets that have the same // values for the Name and Type elements as latency resource record sets. @@ -11777,8 +11402,8 @@ type ResourceRecordSet struct { // a TTL of 60 seconds or less so clients respond quickly to changes in health // status. // - // * All of the resource record sets in a group of weighted, latency, geolocation, - // or failover resource record sets must have the same value for TTL. + // * All of the resource record sets in a group of weighted resource record + // sets must have the same value for TTL. // // * If a group of weighted resource record sets includes one or more weighted // alias resource record sets for which the alias target is an ELB load balancer, @@ -12062,10 +11687,10 @@ func (s *ResourceTagSet) SetTags(v []*Tag) *ResourceTagSet { type StatusReport struct { _ struct{} `type:"structure"` - // The time at which the health checker performed the health check in ISO 8601 - // format (https://en.wikipedia.org/wiki/ISO_8601) and Coordinated Universal - // Time (UTC). For example, the value 2014-10-27T17:48:16.751Z represents October - // 27, 2014 at 17:48:16.751 UTC. + // The date and time that the health checker performed the health check in ISO + // 8601 format (https://en.wikipedia.org/wiki/ISO_8601) and Coordinated Universal + // Time (UTC). For example, the value 2017-03-27T17:48:16.751Z represents March + // 27, 2017 at 17:48:16.751 UTC. CheckedTime *time.Time `type:"timestamp" timestampFormat:"iso8601"` // A description of the status of the health check endpoint as reported by one @@ -12106,8 +11731,8 @@ type Tag struct { // * Add a tag to a health check or hosted zone: Key is the name that you // want to give the new tag. // - // * Edit a tag: Key is the name of the tag whose Value element you want - // to remove. + // * Edit a tag: Key is the name of the tag that you want to change the Value + // for. // // * Delete a key: Key is the name of the tag you want to remove. // @@ -12150,43 +11775,21 @@ func (s *Tag) SetValue(v string) *Tag { // Gets the value that Amazon Route 53 returns in response to a DNS request // for a specified record name and type. You can optionally specify the IP address // of a DNS resolver, an EDNS0 client subnet IP address, and a subnet mask. -// -// Parameters -// -// hostedzoneidThe ID of the hosted zone that you want Amazon Route 53 to simulate -// a query for. -// -// recordnameThe name of the resource record set that you want Amazon Route -// 53 to simulate a query for. -// -// recordtypeThe type of the resource record set. -// -// resolverip (optional)If you want to simulate a request from a specific DNS -// resolver, specify the IP address for that resolver. If you omit this value, -// TestDNSAnswer uses the IP address of a DNS resolver in the AWS US East region. -// -// edns0clientsubnetip (optional)If the resolver that you specified for resolverip -// supports EDNS0, specify the IP address of a client in the applicable location. -// -// edns0clientsubnetmask (optional)If you specify an IP address for edns0clientsubnetip, -// you can optionally specify the number of bits of the IP address that you -// want the checking tool to include in the DNS query. For example, if you specify -// 192.0.2.44 for edns0clientsubnetip and 24 for edns0clientsubnetmask, the -// checking tool will simulate a request from 192.0.2.0/24. The default value -// is 24 bits. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/TestDNSAnswerRequest type TestDNSAnswerInput struct { _ struct{} `type:"structure"` // If the resolver that you specified for resolverip supports EDNS0, specify - // the IP address of a client in the applicable location. + // the IPv4 or IPv6 address of a client in the applicable location, for example, + // 192.0.2.44 or 2001:db8:85a3::8a2e:370:7334. EDNS0ClientSubnetIP *string `location:"querystring" locationName:"edns0clientsubnetip" type:"string"` // If you specify an IP address for edns0clientsubnetip, you can optionally // specify the number of bits of the IP address that you want the checking tool // to include in the DNS query. For example, if you specify 192.0.2.44 for edns0clientsubnetip // and 24 for edns0clientsubnetmask, the checking tool will simulate a request - // from 192.0.2.0/24. The default value is 24 bits. + // from 192.0.2.0/24. The default value is 24 bits for IPv4 addresses and 64 + // bits for IPv6 addresses. EDNS0ClientSubnetMask *string `location:"querystring" locationName:"edns0clientsubnetmask" type:"string"` // The ID of the hosted zone that you want Amazon Route 53 to simulate a query @@ -12208,7 +11811,8 @@ type TestDNSAnswerInput struct { // If you want to simulate a request from a specific DNS resolver, specify the // IP address for that resolver. If you omit this value, TestDnsAnswer uses - // the IP address of a DNS resolver in the AWS US East region. + // the IP address of a DNS resolver in the AWS US East (N. Virginia) Region + // (us-east-1). ResolverIP *string `location:"querystring" locationName:"resolverip" type:"string"` } @@ -12657,7 +12261,8 @@ func (s *TrafficPolicySummary) SetType(v string) *TrafficPolicySummary { return s } -// A complex type that contains the health check request information. +// A complex type that contains information about a request to update a health +// check. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateHealthCheckRequest type UpdateHealthCheckInput struct { _ struct{} `locationName:"UpdateHealthCheckRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` @@ -12781,7 +12386,7 @@ type UpdateHealthCheckInput struct { // and that you include that value in your UpdateHealthCheck request. This prevents // Amazon Route 53 from overwriting an intervening update: // - // * f the value in the UpdateHealthCheck request matches the value of HealthCheckVersion + // * If the value in the UpdateHealthCheck request matches the value of HealthCheckVersion // in the health check, Amazon Route 53 updates the health check with the // new settings. // @@ -12826,8 +12431,13 @@ type UpdateHealthCheckInput struct { // If the endpoint is an EC2 instance, we recommend that you create an Elastic // IP address, associate it with your EC2 instance, and specify the Elastic // IP address for IPAddress. This ensures that the IP address of your instance - // never changes. For more information, see Elastic IP Addresses (EIP) (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) - // in the Amazon EC2 User Guide for Linux Instances. + // never changes. For more information, see the applicable documentation: + // + // * Linux: Elastic IP Addresses (EIP) (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) + // in the Amazon EC2 User Guide for Linux Instances + // + // * Windows: Elastic IP Addresses (EIP) (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/elastic-ip-addresses-eip.html) + // in the Amazon EC2 User Guide for Windows Instances // // If a health check already has a value for IPAddress, you can change the value. // However, you can't update an existing health check to add or remove the value @@ -12869,8 +12479,8 @@ type UpdateHealthCheckInput struct { // checks. Port *int64 `min:"1" type:"integer"` - // A complex type that contains one Region element for each region from which - // you want Amazon Route 53 health checkers to check the specified endpoint. + // A complex type that contains one Region element for each region that you + // want Amazon Route 53 health checkers to check the specified endpoint from. Regions []*string `locationNameList:"Region" min:"1" type:"list"` // The path that you want Amazon Route 53 to request when performing health @@ -13046,7 +12656,7 @@ func (s *UpdateHealthCheckOutput) SetHealthCheck(v *HealthCheck) *UpdateHealthCh return s } -// A complex type that contains the hosted zone request information. +// A request to update the comment for a hosted zone. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateHostedZoneCommentRequest type UpdateHostedZoneCommentInput struct { _ struct{} `locationName:"UpdateHostedZoneCommentRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` @@ -13055,7 +12665,7 @@ type UpdateHostedZoneCommentInput struct { // Amazon Route 53 deletes the existing value of the Comment element, if any. Comment *string `type:"string"` - // The ID for the hosted zone for which you want to update the comment. + // The ID for the hosted zone that you want to update the comment for. // // Id is a required field Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` @@ -13096,7 +12706,8 @@ func (s *UpdateHostedZoneCommentInput) SetId(v string) *UpdateHostedZoneCommentI return s } -// A complex type that contains the response to the UpdateHostedZoneCommentRequest. +// A complex type that contains the response to the UpdateHostedZoneComment +// request. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateHostedZoneCommentResponse type UpdateHostedZoneCommentOutput struct { _ struct{} `type:"structure"` @@ -13123,8 +12734,8 @@ func (s *UpdateHostedZoneCommentOutput) SetHostedZone(v *HostedZone) *UpdateHost return s } -// A complex type that contains information about the traffic policy for which -// you want to update the comment. +// A complex type that contains information about the traffic policy that you +// want to update the comment for. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateTrafficPolicyCommentRequest type UpdateTrafficPolicyCommentInput struct { _ struct{} `locationName:"UpdateTrafficPolicyCommentRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` @@ -13134,13 +12745,14 @@ type UpdateTrafficPolicyCommentInput struct { // Comment is a required field Comment *string `type:"string" required:"true"` - // The value of Id for the traffic policy for which you want to update the comment. + // The value of Id for the traffic policy that you want to update the comment + // for. // // Id is a required field Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` - // The value of Version for the traffic policy for which you want to update - // the comment. + // The value of Version for the traffic policy that you want to update the comment + // for. // // Version is a required field Version *int64 `location:"uri" locationName:"Version" min:"1" type:"integer" required:"true"` @@ -13349,17 +12961,16 @@ func (s *UpdateTrafficPolicyInstanceOutput) SetTrafficPolicyInstance(v *TrafficP return s } -// A complex type that contains information about an Amazon VPC that is associated -// with a private hosted zone. +// (Private hosted zones only) A complex type that contains information about +// an Amazon VPC. // Please also see https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/VPC type VPC struct { _ struct{} `type:"structure"` - // The ID of an Amazon VPC. + // (Private hosted zones only) The ID of an Amazon VPC. VPCId *string `type:"string"` - // The region in which you created the VPC that you want to associate with the - // specified Amazon Route 53 hosted zone. + // (Private hosted zones only) The region in which you created an Amazon VPC. VPCRegion *string `min:"1" type:"string" enum:"VPCRegion"` } diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/errors.go b/vendor/github.com/aws/aws-sdk-go/service/route53/errors.go index 6dcbc3f03..a47d84260 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/route53/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/errors.go @@ -69,8 +69,14 @@ const ( // "HealthCheckAlreadyExists". // // The health check you're attempting to create already exists. Amazon Route - // 53 returns this error when a health check has already been created with the - // specified value for CallerReference. + // 53 returns this error when you submit a request that has the following values: + // + // * The same value for CallerReference as an existing health check, and + // one or more values that differ from the existing health check that has + // the same caller reference. + // + // * The same value for CallerReference as a health check that you created + // and later deleted, regardless of the other settings in the request. ErrCodeHealthCheckAlreadyExists = "HealthCheckAlreadyExists" // ErrCodeHealthCheckInUse for service response error code diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go index 3f0fc2fdc..6799ce85d 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go @@ -3223,17 +3223,15 @@ func (c *S3) HeadObjectRequest(input *HeadObjectInput) (req *request.Request, ou // object itself. This operation is useful if you're only interested in an object's // metadata. To use HEAD, you must have READ access to the object. // +// See http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#RESTErrorResponses +// for more information on returned errors. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation HeadObject for usage and error information. -// -// Returned Error Codes: -// * ErrCodeNoSuchKey "NoSuchKey" -// The specified key does not exist. -// // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject func (c *S3) HeadObject(input *HeadObjectInput) (*HeadObjectOutput, error) { req, out := c.HeadObjectRequest(input) diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go b/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go index c3a2702da..83547047a 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go @@ -12,6 +12,69 @@ import ( var reBucketLocation = regexp.MustCompile(`>([^<>]+)<\/Location`) +// NormalizeBucketLocation is a utility function which will update the +// passed in value to always be a region ID. Generally this would be used +// with GetBucketLocation API operation. +// +// Replaces empty string with "us-east-1", and "EU" with "eu-west-1". +// +// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html +// for more information on the values that can be returned. +func NormalizeBucketLocation(loc string) string { + switch loc { + case "": + loc = "us-east-1" + case "EU": + loc = "eu-west-1" + } + + return loc +} + +// NormalizeBucketLocationHandler is a request handler which will update the +// GetBucketLocation's result LocationConstraint value to always be a region ID. +// +// Replaces empty string with "us-east-1", and "EU" with "eu-west-1". +// +// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html +// for more information on the values that can be returned. +// +// req, result := svc.GetBucketLocationRequest(&s3.GetBucketLocationInput{ +// Bucket: aws.String(bucket), +// }) +// req.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler) +// err := req.Send() +var NormalizeBucketLocationHandler = request.NamedHandler{ + Name: "awssdk.s3.NormalizeBucketLocation", + Fn: func(req *request.Request) { + if req.Error != nil { + return + } + + out := req.Data.(*GetBucketLocationOutput) + loc := NormalizeBucketLocation(aws.StringValue(out.LocationConstraint)) + out.LocationConstraint = aws.String(loc) + }, +} + +// WithNormalizeBucketLocation is a request option which will update the +// GetBucketLocation's result LocationConstraint value to always be a region ID. +// +// Replaces empty string with "us-east-1", and "EU" with "eu-west-1". +// +// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html +// for more information on the values that can be returned. +// +// result, err := svc.GetBucketLocationWithContext(ctx, +// &s3.GetBucketLocationInput{ +// Bucket: aws.String(bucket), +// }, +// WithNormalizeBucketLocation, +// ) +func WithNormalizeBucketLocation(r *request.Request) { + r.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler) +} + func buildGetBucketLocation(r *request.Request) { if r.DataFilled() { out := r.Data.(*GetBucketLocationOutput) @@ -24,7 +87,7 @@ func buildGetBucketLocation(r *request.Request) { match := reBucketLocation.FindSubmatch(b) if len(match) > 1 { loc := string(match[1]) - out.LocationConstraint = &loc + out.LocationConstraint = aws.String(loc) } } } diff --git a/vendor/github.com/xanzy/go-gitlab/CHANGELOG.md b/vendor/github.com/xanzy/go-gitlab/CHANGELOG.md new file mode 100644 index 000000000..09cb6db4d --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/CHANGELOG.md @@ -0,0 +1,22 @@ +go-github CHANGELOG +=================== + +0.4.0 +----- +- Add support to use [`sudo`](https://docs.gitlab.com/ce/api/README.html#sudo) for all API calls. +- Add support for the Notification Settings API. +- Add support for the Time Tracking API. +- Make sure that the error response correctly outputs any returned errors. +- And a reasonable number of smaller enhanchements and bugfixes. + +0.3.0 +----- +- Moved the tags related API calls to their own service, following the Gitlab API structure. + +0.2.0 +----- +- Convert all Option structs to use pointers for their fields. + +0.1.0 +----- +- Initial release. diff --git a/vendor/github.com/xanzy/go-gitlab/LICENSE b/vendor/github.com/xanzy/go-gitlab/LICENSE new file mode 100644 index 000000000..e06d20818 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/github.com/xanzy/go-gitlab/README.md b/vendor/github.com/xanzy/go-gitlab/README.md new file mode 100644 index 000000000..7b6d1bcfd --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/README.md @@ -0,0 +1,125 @@ +# go-gitlab + +A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way + +**Documentation:** [![GoDoc](https://godoc.org/github.com/xanzy/go-gitlab?status.svg)](https://godoc.org/github.com/xanzy/go-gitlab) +**Build Status:** [![Build Status](https://travis-ci.org/xanzy/go-gitlab.svg?branch=master)](https://travis-ci.org/xanzy/go-gitlab) + +## NOTE + +Release v0.5.0 (released on 22-03-2017) no longer supports Go versions older +then 1.7.x If you want (or need) to use an older Go version please use v0.4.1 + +## Coverage + +This API client package covers **100%** of the existing GitLab API calls! So this +includes all calls to the following services: + +- [x] Users +- [x] Session +- [x] Projects (including setting Webhooks) +- [x] Project Snippets +- [x] Services +- [x] Repositories +- [x] Repository Files +- [x] Commits +- [x] Branches +- [x] Merge Requests +- [x] Issues +- [x] Labels +- [x] Milestones +- [x] Notes (comments) +- [x] Deploy Keys +- [x] System Hooks +- [x] Groups +- [x] Namespaces +- [x] Settings +- [x] Pipelines + +## Usage + +```go +import "github.com/xanzy/go-gitlab" +``` + +Construct a new GitLab client, then use the various services on the client to +access different parts of the GitLab API. For example, to list all +users: + +```go +git := gitlab.NewClient(nil, "yourtokengoeshere") +//git.SetBaseURL("https://git.mydomain.com/api/v3") +users, _, err := git.Users.ListUsers() +``` + +Some API methods have optional parameters that can be passed. For example, +to list all projects for user "svanharmelen": + +```go +git := gitlab.NewClient(nil) +opt := &ListProjectsOptions{Search: gitlab.String("svanharmelen")}) +projects, _, err := git.Projects.ListProjects(opt) +``` + +### Examples + +The [examples](https://github.com/xanzy/go-gitlab/tree/master/examples) directory +contains a couple for clear examples, of which one is partially listed here as well: + +```go +package main + +import ( + "log" + + "github.com/xanzy/go-gitlab" +) + +func main() { + git := gitlab.NewClient(nil, "yourtokengoeshere") + + // Create new project + p := &gitlab.CreateProjectOptions{ + Name: gitlab.String("My Project"), + Description: gitlab.String("Just a test project to play with"), + MergeRequestsEnabled: gitlab.Bool(true), + SnippetsEnabled: gitlab.Bool(true), + VisibilityLevel: gitlab.VisibilityLevel(gitlab.PublicVisibility), + } + project, _, err := git.Projects.CreateProject(p) + if err != nil { + log.Fatal(err) + } + + // Add a new snippet + s := &gitlab.CreateSnippetOptions{ + Title: gitlab.String("Dummy Snippet"), + FileName: gitlab.String("snippet.go"), + Code: gitlab.String("package main...."), + VisibilityLevel: gitlab.VisibilityLevel(gitlab.PublicVisibility), + } + _, _, err = git.ProjectSnippets.CreateSnippet(project.ID, s) + if err != nil { + log.Fatal(err) + } +} + +``` + +For complete usage of go-gitlab, see the full [package docs](https://godoc.org/github.com/xanzy/go-gitlab). + +## ToDo + +- The biggest thing this package still needs is tests :disappointed: + +## Issues + +- If you have an issue: report it on the [issue tracker](https://github.com/xanzy/go-gitlab/issues) + +## Author + +Sander van Harmelen () + +## License + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/vendor/github.com/xanzy/go-gitlab/branches.go b/vendor/github.com/xanzy/go-gitlab/branches.go new file mode 100644 index 000000000..adb4c739b --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/branches.go @@ -0,0 +1,201 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" +) + +// BranchesService handles communication with the branch related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html +type BranchesService struct { + client *Client +} + +// Branch represents a GitLab branch. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html +type Branch struct { + Commit *Commit `json:"commit"` + Name string `json:"name"` + Protected bool `json:"protected"` +} + +func (b Branch) String() string { + return Stringify(b) +} + +// ListBranches gets a list of repository branches from a project, sorted by +// name alphabetically. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/branches.html#list-repository-branches +func (s *BranchesService) ListBranches(pid interface{}, options ...OptionFunc) ([]*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var b []*Branch + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b, resp, err +} + +// GetBranch gets a single project repository branch. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/branches.html#get-single-repository-branch +func (s *BranchesService) GetBranch(pid interface{}, branch string, options ...OptionFunc) (*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches/%s", url.QueryEscape(project), branch) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + b := new(Branch) + resp, err := s.client.Do(req, b) + if err != nil { + return nil, resp, err + } + + return b, resp, err +} + +// ProtectBranch protects a single project repository branch. This is an +// idempotent function, protecting an already protected repository branch +// still returns a 200 OK status code. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/branches.html#protect-repository-branch +func (s *BranchesService) ProtectBranch(pid interface{}, branch string, options ...OptionFunc) (*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches/%s/protect", url.QueryEscape(project), branch) + + req, err := s.client.NewRequest("PUT", u, nil, options) + if err != nil { + return nil, nil, err + } + + b := new(Branch) + resp, err := s.client.Do(req, b) + if err != nil { + return nil, resp, err + } + + return b, resp, err +} + +// UnprotectBranch unprotects a single project repository branch. This is an +// idempotent function, unprotecting an already unprotected repository branch +// still returns a 200 OK status code. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/branches.html#unprotect-repository-branch +func (s *BranchesService) UnprotectBranch(pid interface{}, branch string, options ...OptionFunc) (*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches/%s/unprotect", url.QueryEscape(project), branch) + + req, err := s.client.NewRequest("PUT", u, nil, options) + if err != nil { + return nil, nil, err + } + + b := new(Branch) + resp, err := s.client.Do(req, b) + if err != nil { + return nil, resp, err + } + + return b, resp, err +} + +// CreateBranchOptions represents the available CreateBranch() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch +type CreateBranchOptions struct { + BranchName *string `url:"branch_name,omitempty" json:"branch_name,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// CreateBranch creates branch from commit SHA or existing branch. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch +func (s *BranchesService) CreateBranch(pid interface{}, opt *CreateBranchOptions, options ...OptionFunc) (*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + b := new(Branch) + resp, err := s.client.Do(req, b) + if err != nil { + return nil, resp, err + } + + return b, resp, err +} + +// DeleteBranch deletes an existing branch. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/branches.html#delete-repository-branch +func (s *BranchesService) DeleteBranch(pid interface{}, branch string, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches/%s", url.QueryEscape(project), branch) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/build_variables.go b/vendor/github.com/xanzy/go-gitlab/build_variables.go new file mode 100644 index 000000000..a1bdf7f65 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/build_variables.go @@ -0,0 +1,146 @@ +package gitlab + +import ( + "fmt" + "net/url" +) + +// BuildVariablesService handles communication with the project variables related methods +// of the Gitlab API +// +// Gitlab API Docs : https://docs.gitlab.com/ce/api/build_variables.html +type BuildVariablesService struct { + client *Client +} + +// BuildVariable represents a variable available for each build of the given project +// +// Gitlab API Docs : https://docs.gitlab.com/ce/api/build_variables.html +type BuildVariable struct { + Key string `json:"key"` + Value string `json:"value"` +} + +func (v BuildVariable) String() string { + return Stringify(v) +} + +// ListBuildVariables gets the a list of project variables in a project +// +// Gitlab API Docs: +// https://docs.gitlab.com/ce/api/build_variables.html#list-project-variables +func (s *BuildVariablesService) ListBuildVariables(pid interface{}, options ...OptionFunc) ([]*BuildVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var v []*BuildVariable + resp, err := s.client.Do(req, &v) + if err != nil { + return nil, resp, err + } + + return v, resp, err +} + +// GetBuildVariable gets a single project variable of a project +// +// Gitlab API Docs: +// https://docs.gitlab.com/ce/api/build_variables.html#show-variable-details +func (s *BuildVariablesService) GetBuildVariable(pid interface{}, key string, options ...OptionFunc) (*BuildVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + v := new(BuildVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, err +} + +// CreateBuildVariable creates a variable for a given project +// +// Gitlab API Docs: +// https://docs.gitlab.com/ce/api/build_variables.html#create-variable +func (s *BuildVariablesService) CreateBuildVariable(pid interface{}, key, value string, options ...OptionFunc) (*BuildVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, BuildVariable{key, value}, options) + if err != nil { + return nil, nil, err + } + + v := new(BuildVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, err +} + +// UpdateBuildVariable updates an existing project variable +// The variable key must exist +// +// Gitlab API Docs: +// https://docs.gitlab.com/ce/api/build_variables.html#update-variable +func (s *BuildVariablesService) UpdateBuildVariable(pid interface{}, key, value string, options ...OptionFunc) (*BuildVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key) + + req, err := s.client.NewRequest("PUT", u, BuildVariable{key, value}, options) + if err != nil { + return nil, nil, err + } + + v := new(BuildVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, err +} + +// RemoveBuildVariable removes a project variable of a given project identified by its key +// +// Gitlab API Docs: +// https://docs.gitlab.com/ce/api/build_variables.html#remove-variable +func (s *BuildVariablesService) RemoveBuildVariable(pid interface{}, key string, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/builds.go b/vendor/github.com/xanzy/go-gitlab/builds.go new file mode 100644 index 000000000..dfee85b32 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/builds.go @@ -0,0 +1,349 @@ +// +// Copyright 2016, Arkbriar +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "io" + "net/url" + "time" +) + +// ListBuildsOptions are options for two list apis +type ListBuildsOptions struct { + ListOptions + Scope []BuildState `url:"scope,omitempty" json:"scope,omitempty"` +} + +// BuildsService handles communication with the ci builds related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/builds.html +type BuildsService struct { + client *Client +} + +// Build represents a ci build. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/builds.html +type Build struct { + Commit *Commit `json:"commit"` + CreatedAt *time.Time `json:"created_at"` + ArtifactsFile struct { + Filename string `json:"filename"` + Size int `json:"size"` + } `json:"artifacts_file"` + FinishedAt *time.Time `json:"finished_at"` + ID int `json:"id"` + Name string `json:"name"` + Ref string `json:"ref"` + Runner struct { + ID int `json:"id"` + Description string `json:"description"` + Active bool `json:"active"` + IsShared bool `json:"is_shared"` + Name string `json:"name"` + } `json:"runner"` + Stage string `json:"stage"` + StartedAt *time.Time `json:"started_at"` + Status string `json:"status"` + Tag bool `json:"tag"` + User *User `json:"user"` +} + +// ListProjectBuilds gets a list of builds in a project. +// +// The scope of builds to show, one or array of: pending, running, +// failed, success, canceled; showing all builds if none provided. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#list-project-builds +func (s *BuildsService) ListProjectBuilds(pid interface{}, opts *ListBuildsOptions, options ...OptionFunc) ([]Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opts, options) + if err != nil { + return nil, nil, err + } + + var builds []Build + resp, err := s.client.Do(req, &builds) + if err != nil { + return nil, resp, err + } + + return builds, resp, err +} + +// ListCommitBuilds gets a list of builds for specific commit in a +// project. If the commit SHA is not found, it will respond with 404. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#list-commit-builds +func (s *BuildsService) ListCommitBuilds(pid interface{}, sha string, opts *ListBuildsOptions, options ...OptionFunc) ([]Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/builds", project, sha) + + req, err := s.client.NewRequest("GET", u, opts, options) + if err != nil { + return nil, nil, err + } + + var builds []Build + resp, err := s.client.Do(req, &builds) + if err != nil { + return nil, resp, err + } + + return builds, resp, err +} + +// GetBuild gets a single build of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#get-a-single-build +func (s *BuildsService) GetBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d", project, buildID) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + build := new(Build) + resp, err := s.client.Do(req, build) + if err != nil { + return nil, resp, err + } + + return build, resp, err +} + +// GetBuildArtifacts get builds artifacts of a project +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#get-build-artifacts +func (s *BuildsService) GetBuildArtifacts(pid interface{}, buildID int, options ...OptionFunc) (io.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d/artifacts", project, buildID) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + artifactsBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, artifactsBuf) + if err != nil { + return nil, resp, err + } + + return artifactsBuf, resp, err +} + +// DownloadArtifactsFile download the artifacts file from the given +// reference name and job provided the build finished successfully. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#download-the-artifacts-file +func (s *BuildsService) DownloadArtifactsFile(pid interface{}, refName string, job string, options ...OptionFunc) (io.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/artifacts/%s/download?job=%s", project, refName, job) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + artifactsBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, artifactsBuf) + if err != nil { + return nil, resp, err + } + + return artifactsBuf, resp, err +} + +// GetTraceFile gets a trace of a specific build of a project +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#get-a-trace-file +func (s *BuildsService) GetTraceFile(pid interface{}, buildID int, options ...OptionFunc) (io.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d/trace", project, buildID) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + traceBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, traceBuf) + if err != nil { + return nil, resp, err + } + + return traceBuf, resp, err +} + +// CancelBuild cancels a single build of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#cancel-a-build +func (s *BuildsService) CancelBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d/cancel", project, buildID) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + build := new(Build) + resp, err := s.client.Do(req, build) + if err != nil { + return nil, resp, err + } + + return build, resp, err +} + +// RetryBuild retries a single build of a project +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#retry-a-build +func (s *BuildsService) RetryBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d/retry", project, buildID) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + build := new(Build) + resp, err := s.client.Do(req, build) + if err != nil { + return nil, resp, err + } + + return build, resp, err +} + +// EraseBuild erases a single build of a project, removes a build +// artifacts and a build trace. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#erase-a-build +func (s *BuildsService) EraseBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d/erase", project, buildID) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + build := new(Build) + resp, err := s.client.Do(req, build) + if err != nil { + return nil, resp, err + } + + return build, resp, err +} + +// KeepArtifacts prevents artifacts from being deleted when +// expiration is set. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#keep-artifacts +func (s *BuildsService) KeepArtifacts(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d/artifacts/keep", project, buildID) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + build := new(Build) + resp, err := s.client.Do(req, build) + if err != nil { + return nil, resp, err + } + + return build, resp, err +} + +// PlayBuild triggers a nanual action to start a build. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/builds.html#play-a-build +func (s *BuildsService) PlayBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/builds/%d/play", project, buildID) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + build := new(Build) + resp, err := s.client.Do(req, build) + if err != nil { + return nil, resp, err + } + + return build, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/commits.go b/vendor/github.com/xanzy/go-gitlab/commits.go new file mode 100644 index 000000000..7aa642c52 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/commits.go @@ -0,0 +1,444 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// CommitsService handles communication with the commit related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html +type CommitsService struct { + client *Client +} + +// Commit represents a GitLab commit. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html +type Commit struct { + ID string `json:"id"` + ShortID string `json:"short_id"` + Title string `json:"title"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + AuthoredDate *time.Time `json:"authored_date"` + CommitterName string `json:"committer_name"` + CommitterEmail string `json:"committer_email"` + CommittedDate *time.Time `json:"committed_date"` + CreatedAt *time.Time `json:"created_at"` + Message string `json:"message"` + ParentIDs []string `json:"parent_ids"` + Stats *CommitStats `json:"stats"` + Status *BuildState `json:"status"` +} + +// CommitStats represents the number of added and deleted files in a commit. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html +type CommitStats struct { + Additions int `json:"additions"` + Deletions int `json:"deletions"` + Total int `json:"total"` +} + +func (c Commit) String() string { + return Stringify(c) +} + +// ListCommitsOptions represents the available ListCommits() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-repository-commits +type ListCommitsOptions struct { + ListOptions + RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"` + Since time.Time `url:"since,omitempty" json:"since,omitempty"` + Until time.Time `url:"until,omitempty" json:"until,omitempty"` +} + +// ListCommits gets a list of repository commits in a project. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-commits +func (s *CommitsService) ListCommits(pid interface{}, opt *ListCommitsOptions, options ...OptionFunc) ([]*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var c []*Commit + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} + +// FileAction represents the available actions that can be performed on a file. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions +type FileAction string + +// The available file actions. +const ( + FileCreate FileAction = "create" + FileDelete FileAction = "delete" + FileMove FileAction = "move" + FileUpdate FileAction = "update" +) + +// CommitAction represents a single file action within a commit. +type CommitAction struct { + Action FileAction `url:"action" json:"action,omitempty"` + FilePath string `url:"file_path" json:"file_path,omitempty"` + PreviousPath string `url:"previous_path,omitempty" json:"previous_path,omitempty"` + Content string `url:"content,omitempty" json:"content,omitempty"` + Encoding string `url:"encoding,omitempty" json:"encoding,omitempty"` +} + +// CreateCommitOptions represents the available options for a new commit. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions +type CreateCommitOptions struct { + BranchName *string `url:"branch_name" json:"branch_name,omitempty"` + CommitMessage *string `url:"commit_message" json:"commit_message,omitempty"` + Actions []*CommitAction `url:"actions" json:"actions,omitempty"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` +} + +// CreateCommit creates a commit with multiple files and actions. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions +func (s *CommitsService) CreateCommit(pid interface{}, opt *CreateCommitOptions, options ...OptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + var c *Commit + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} + +// GetCommit gets a specific commit identified by the commit hash or name of a +// branch or tag. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-a-single-commit +func (s *CommitsService) GetCommit(pid interface{}, sha string, options ...OptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + c := new(Commit) + resp, err := s.client.Do(req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} + +// Diff represents a GitLab diff. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html +type Diff struct { + Diff string `json:"diff"` + NewPath string `json:"new_path"` + OldPath string `json:"old_path"` + AMode string `json:"a_mode"` + BMode string `json:"b_mode"` + NewFile bool `json:"new_file"` + RenamedFile bool `json:"renamed_file"` + DeletedFile bool `json:"deleted_file"` +} + +func (d Diff) String() string { + return Stringify(d) +} + +// GetCommitDiff gets the diff of a commit in a project.. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit +func (s *CommitsService) GetCommitDiff(pid interface{}, sha string, options ...OptionFunc) ([]*Diff, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/diff", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var d []*Diff + resp, err := s.client.Do(req, &d) + if err != nil { + return nil, resp, err + } + + return d, resp, err +} + +// CommitComment represents a GitLab commit comment. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html +type CommitComment struct { + Note string `json:"note"` + Path string `json:"path"` + Line int `json:"line"` + LineType string `json:"line_type"` + Author Author `json:"author"` +} + +// Author represents a GitLab commit author +type Author struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + Blocked bool `json:"blocked"` + CreatedAt *time.Time `json:"created_at"` +} + +func (c CommitComment) String() string { + return Stringify(c) +} + +// GetCommitComments gets the comments of a commit in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit +func (s *CommitsService) GetCommitComments(pid interface{}, sha string, options ...OptionFunc) ([]*CommitComment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var c []*CommitComment + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} + +// PostCommitCommentOptions represents the available PostCommitComment() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit +type PostCommitCommentOptions struct { + Note *string `url:"note,omitempty" json:"note,omitempty"` + Path *string `url:"path" json:"path"` + Line *int `url:"line" json:"line"` + LineType *string `url:"line_type" json:"line_type"` +} + +// PostCommitComment adds a comment to a commit. Optionally you can post +// comments on a specific line of a commit. Therefor both path, line_new and +// line_old are required. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit +func (s *CommitsService) PostCommitComment(pid interface{}, sha string, opt *PostCommitCommentOptions, options ...OptionFunc) (*CommitComment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(CommitComment) + resp, err := s.client.Do(req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} + +// GetCommitStatusesOptions represents the available GetCommitStatuses() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit +type GetCommitStatusesOptions struct { + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Stage *string `url:"stage,omitempty" json:"stage,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + All *bool `url:"all,omitempty" json:"all,omitempty"` +} + +// CommitStatus represents a GitLab commit status. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit +type CommitStatus struct { + ID int `json:"id"` + SHA string `json:"sha"` + Ref string `json:"ref"` + Status string `json:"status"` + Name string `json:"name"` + TargetURL string `json:"target_url"` + Description string `json:"description"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + Author Author `json:"author"` +} + +// GetCommitStatuses gets the statuses of a commit in a project. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit +func (s *CommitsService) GetCommitStatuses(pid interface{}, sha string, opt *GetCommitStatusesOptions, options ...OptionFunc) ([]*CommitStatus, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/statuses", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var cs []*CommitStatus + resp, err := s.client.Do(req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, err +} + +// SetCommitStatusOptions represents the available SetCommitStatus() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit +type SetCommitStatusOptions struct { + State BuildState `url:"state" json:"state"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Context *string `url:"context,omitempty" json:"context,omitempty"` + TargetURL *string `url:"target_url,omitempty" json:"target_url,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` +} + +// BuildState represents a GitLab build state. +type BuildState string + +// These constants represent all valid build states. +const ( + Pending BuildState = "pending" + Running BuildState = "running" + Success BuildState = "success" + Failed BuildState = "failed" + Canceled BuildState = "canceled" +) + +// SetCommitStatus sets the status of a commit in a project. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit +func (s *CommitsService) SetCommitStatus(pid interface{}, sha string, opt *SetCommitStatusOptions, options ...OptionFunc) (*CommitStatus, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/statuses/%s", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + var cs *CommitStatus + resp, err := s.client.Do(req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, err +} + +// CherryPickCommitOptions represents the available options for cherry-picking a commit. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit +type CherryPickCommitOptions struct { + TargetBranch *string `url:"branch" json:"branch,omitempty"` +} + +// CherryPickCommit sherry picks a commit to a given branch. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit +func (s *CommitsService) CherryPickCommit(pid interface{}, sha string, opt *CherryPickCommitOptions, options ...OptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/cherry_pick", + url.QueryEscape(project), url.QueryEscape(sha)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + var c *Commit + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/deploy_keys.go b/vendor/github.com/xanzy/go-gitlab/deploy_keys.go new file mode 100644 index 000000000..1e9eae857 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/deploy_keys.go @@ -0,0 +1,150 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// DeployKeysService handles communication with the keys related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/deploy_keys.html +type DeployKeysService struct { + client *Client +} + +// DeployKey represents a GitLab deploy key. +type DeployKey struct { + ID int `json:"id"` + Title string `json:"title"` + Key string `json:"key"` + CanPush *bool `json:"can_push"` + CreatedAt *time.Time `json:"created_at"` +} + +func (k DeployKey) String() string { + return Stringify(k) +} + +// ListDeployKeys gets a list of a project's deploy keys +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/deploy_keys.html#list-deploy-keys +func (s *DeployKeysService) ListDeployKeys(pid interface{}, options ...OptionFunc) ([]*DeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/keys", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var k []*DeployKey + resp, err := s.client.Do(req, &k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// GetDeployKey gets a single deploy key. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/deploy_keys.html#single-deploy-key +func (s *DeployKeysService) GetDeployKey(pid interface{}, deployKey int, options ...OptionFunc) (*DeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/keys/%d", url.QueryEscape(project), deployKey) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(DeployKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// AddDeployKeyOptions represents the available ADDDeployKey() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key +type AddDeployKeyOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Key *string `url:"key,omitempty" json:"key,omitempty"` + CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"` +} + +// AddDeployKey creates a new deploy key for a project. If deploy key already +// exists in another project - it will be joined to project but only if +// original one was is accessible by same user. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key +func (s *DeployKeysService) AddDeployKey(pid interface{}, opt *AddDeployKeyOptions, options ...OptionFunc) (*DeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/keys", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + k := new(DeployKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// DeleteDeployKey deletes a deploy key from a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/deploy_keys.html#delete-deploy-key +func (s *DeployKeysService) DeleteDeployKey(pid interface{}, deployKey int, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/keys/%d", url.QueryEscape(project), deployKey) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/events.go b/vendor/github.com/xanzy/go-gitlab/events.go new file mode 100644 index 000000000..ef334592e --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/events.go @@ -0,0 +1,557 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "time" + +// PushEvent represents a push event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#push-events +type PushEvent struct { + ObjectKind string `json:"object_kind"` + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSha string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserEmail string `json:"user_email"` + UserAvatar string `json:"user_avatar"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Repository *Repository `json:"repository"` + Commits []*Commit `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` +} + +// TagEvent represents a tag event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#tag-events +type TagEvent struct { + ObjectKind string `json:"object_kind"` + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSha string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserAvatar string `json:"user_avatar"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Repository *Repository `json:"repository"` + Commits []*Commit `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` +} + +// IssueEvent represents a issue event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#issues-events +type IssueEvent struct { + ObjectKind string `json:"object_kind"` + User *User `json:"user"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Title string `json:"title"` + AssigneeID int `json:"assignee_id"` + AuthorID int `json:"author_id"` + ProjectID int `json:"project_id"` + CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) + UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) + Position int `json:"position"` + BranchName string `json:"branch_name"` + Description string `json:"description"` + MilestoneID int `json:"milestone_id"` + State string `json:"state"` + Iid int `json:"iid"` + URL string `json:"url"` + Action string `json:"action"` + } `json:"object_attributes"` + Assignee struct { + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + } `json:"assignee"` +} + +// CommitCommentEvent represents a comment on a commit event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-commit +type CommitCommentEvent struct { + ObjectKind string `json:"object_kind"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment string `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + NoteableID int `json:"noteable_id"` + System bool `json:"system"` + StDiff struct { + Diff string `json:"diff"` + NewPath string `json:"new_path"` + OldPath string `json:"old_path"` + AMode string `json:"a_mode"` + BMode string `json:"b_mode"` + NewFile bool `json:"new_file"` + RenamedFile bool `json:"renamed_file"` + DeletedFile bool `json:"deleted_file"` + } `json:"st_diff"` + } `json:"object_attributes"` + Commit *Commit `json:"commit"` +} + +// MergeCommentEvent represents a comment on a merge event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-merge-request +type MergeCommentEvent struct { + ObjectKind string `json:"object_kind"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment string `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + NoteableID int `json:"noteable_id"` + System bool `json:"system"` + StDiff *Diff `json:"st_diff"` + URL string `json:"url"` + } `json:"object_attributes"` + MergeRequest *MergeRequest `json:"merge_request"` +} + +// IssueCommentEvent represents a comment on an issue event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-issue +type IssueCommentEvent struct { + ObjectKind string `json:"object_kind"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment string `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + NoteableID int `json:"noteable_id"` + System bool `json:"system"` + StDiff []*Diff `json:"st_diff"` + URL string `json:"url"` + } `json:"object_attributes"` + Issue *Issue `json:"issue"` +} + +// SnippetCommentEvent represents a comment on a snippet event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-code-snippet +type SnippetCommentEvent struct { + ObjectKind string `json:"object_kind"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment string `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + NoteableID int `json:"noteable_id"` + System bool `json:"system"` + StDiff *Diff `json:"st_diff"` + URL string `json:"url"` + } `json:"object_attributes"` + Snippet *Snippet `json:"snippet"` +} + +// MergeEvent represents a merge event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#merge-request-events +type MergeEvent struct { + ObjectKind string `json:"object_kind"` + User *User `json:"user"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + ObjectAttributes struct { + ID int `json:"id"` + TargetBranch string `json:"target_branch"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + AuthorID int `json:"author_id"` + AssigneeID int `json:"assignee_id"` + Title string `json:"title"` + CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) + UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) + StCommits []*Commit `json:"st_commits"` + StDiffs []*Diff `json:"st_diffs"` + MilestoneID int `json:"milestone_id"` + State string `json:"state"` + MergeStatus string `json:"merge_status"` + TargetProjectID int `json:"target_project_id"` + Iid int `json:"iid"` + Description string `json:"description"` + Position int `json:"position"` + LockedAt string `json:"locked_at"` + UpdatedByID int `json:"updated_by_id"` + MergeError string `json:"merge_error"` + MergeParams struct { + ForceRemoveSourceBranch string `json:"force_remove_source_branch"` + } `json:"merge_params"` + MergeWhenBuildSucceeds bool `json:"merge_when_build_succeeds"` + MergeUserID int `json:"merge_user_id"` + MergeCommitSha string `json:"merge_commit_sha"` + DeletedAt string `json:"deleted_at"` + ApprovalsBeforeMerge string `json:"approvals_before_merge"` + RebaseCommitSha string `json:"rebase_commit_sha"` + InProgressMergeCommitSha string `json:"in_progress_merge_commit_sha"` + LockVersion int `json:"lock_version"` + TimeEstimate int `json:"time_estimate"` + Source *Repository `json:"source"` + Target *Repository `json:"target"` + LastCommit struct { + ID string `json:"id"` + Message string `json:"message"` + Timestamp *time.Time `json:"timestamp"` + URL string `json:"url"` + Author *Author `json:"author"` + } `json:"last_commit"` + WorkInProgress bool `json:"work_in_progress"` + URL string `json:"url"` + Action string `json:"action"` + Assignee struct { + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + } `json:"assignee"` + } `json:"object_attributes"` + Repository *Repository `json:"repository"` + Assignee struct { + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + } `json:"assignee"` +} + +// WikiPageEvent represents a wiki page event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#wiki-page-events +type WikiPageEvent struct { + ObjectKind string `json:"object_kind"` + User *User `json:"user"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Wiki struct { + WebURL string `json:"web_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + } `json:"wiki"` + ObjectAttributes struct { + Title string `json:"title"` + Content string `json:"content"` + Format string `json:"format"` + Message string `json:"message"` + Slug string `json:"slug"` + URL string `json:"url"` + Action string `json:"action"` + } `json:"object_attributes"` +} + +// PipelineEvent represents a pipeline event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#pipeline-events +type PipelineEvent struct { + ObjectKind string `json:"object_kind"` + ObjectAttributes struct { + ID int `json:"id"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + Sha string `json:"sha"` + BeforeSha string `json:"before_sha"` + Status string `json:"status"` + Stages []string `json:"stages"` + CreatedAt string `json:"created_at"` + FinishedAt string `json:"finished_at"` + Duration int `json:"duration"` + } `json:"object_attributes"` + User struct { + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + } `json:"user"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + } `json:"project"` + Commit struct { + ID string `json:"id"` + Message string `json:"message"` + Timestamp time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"commit"` + Builds []struct { + ID int `json:"id"` + Stage string `json:"stage"` + Name string `json:"name"` + Status string `json:"status"` + CreatedAt string `json:"created_at"` + StartedAt string `json:"started_at"` + FinishedAt string `json:"finished_at"` + When string `json:"when"` + Manual bool `json:"manual"` + User struct { + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + } `json:"user"` + Runner string `json:"runner"` + ArtifactsFile struct { + Filename string `json:"filename"` + Size string `json:"size"` + } `json:"artifacts_file"` + } `json:"builds"` +} + +//BuildEvent represents a build event +// +// GitLab API docs: +// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#build-events +type BuildEvent struct { + ObjectKind string `json:"object_kind"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + BeforeSha string `json:"before_sha"` + Sha string `json:"sha"` + BuildID int `json:"build_id"` + BuildName string `json:"build_name"` + BuildStage string `json:"build_stage"` + BuildStatus string `json:"build_status"` + BuildStartedAt string `json:"build_started_at"` + BuildFinishedAt string `json:"build_finished_at"` + BuildDuration string `json:"build_duration"` + BuildAllowFailure bool `json:"build_allow_failure"` + ProjectID int `json:"project_id"` + ProjectName string `json:"project_name"` + User struct { + ID int `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + } `json:"user"` + Commit struct { + ID int `json:"id"` + Sha string `json:"sha"` + Message string `json:"message"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + Status string `json:"status"` + Duration string `json:"duration"` + StartedAt string `json:"started_at"` + FinishedAt string `json:"finished_at"` + } `json:"commit"` + Repository *Repository `json:"repository"` +} diff --git a/vendor/github.com/xanzy/go-gitlab/gitlab.go b/vendor/github.com/xanzy/go-gitlab/gitlab.go new file mode 100644 index 000000000..655485d3c --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/gitlab.go @@ -0,0 +1,605 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + + "github.com/google/go-querystring/query" +) + +const ( + libraryVersion = "0.1.1" + defaultBaseURL = "https://gitlab.com/api/v3/" + userAgent = "go-gitlab/" + libraryVersion +) + +// tokenType represents a token type within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/ +type tokenType int + +// List of available token type +// +// GitLab API docs: https://docs.gitlab.com/ce/api/ +const ( + privateToken tokenType = iota + oAuthToken +) + +// AccessLevelValue represents a permission level within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html +type AccessLevelValue int + +// List of available access levels +// +// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html +const ( + GuestPermissions AccessLevelValue = 10 + ReporterPermissions AccessLevelValue = 20 + DeveloperPermissions AccessLevelValue = 30 + MasterPermissions AccessLevelValue = 40 + OwnerPermission AccessLevelValue = 50 +) + +// NotificationLevelValue represents a notification level. +type NotificationLevelValue int + +// String implements the fmt.Stringer interface. +func (l NotificationLevelValue) String() string { + return notificationLevelNames[l] +} + +// MarshalJSON implements the json.Marshaler interface. +func (l NotificationLevelValue) MarshalJSON() ([]byte, error) { + return json.Marshal(l.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (l *NotificationLevelValue) UnmarshalJSON(data []byte) error { + var raw interface{} + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + switch raw := raw.(type) { + case float64: + *l = NotificationLevelValue(raw) + case string: + *l = notificationLevelTypes[raw] + default: + return fmt.Errorf("json: cannot unmarshal %T into Go value of type %T", raw, *l) + } + + return nil +} + +// List of valid notification levels. +const ( + DisabledNotificationLevel NotificationLevelValue = iota + ParticipatingNotificationLevel + WatchNotificationLevel + GlobalNotificationLevel + MentionNotificationLevel + CustomNotificationLevel +) + +var notificationLevelNames = [...]string{ + "disabled", + "participating", + "watch", + "global", + "mention", + "custom", +} + +var notificationLevelTypes = map[string]NotificationLevelValue{ + "disabled": DisabledNotificationLevel, + "participating": ParticipatingNotificationLevel, + "watch": WatchNotificationLevel, + "global": GlobalNotificationLevel, + "mention": MentionNotificationLevel, + "custom": CustomNotificationLevel, +} + +// VisibilityLevelValue represents a visibility level within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/ +type VisibilityLevelValue int + +// List of available visibility levels +// +// GitLab API docs: https://docs.gitlab.com/ce/api/ +const ( + PrivateVisibility VisibilityLevelValue = 0 + InternalVisibility VisibilityLevelValue = 10 + PublicVisibility VisibilityLevelValue = 20 +) + +// A Client manages communication with the GitLab API. +type Client struct { + // HTTP client used to communicate with the API. + client *http.Client + + // Base URL for API requests. Defaults to the public GitLab API, but can be + // set to a domain endpoint to use with aself hosted GitLab server. baseURL + // should always be specified with a trailing slash. + baseURL *url.URL + + // token type used to make authenticated API calls. + tokenType tokenType + + // token used to make authenticated API calls. + token string + + // User agent used when communicating with the GitLab API. + UserAgent string + + // Services used for talking to different parts of the GitLab API. + Branches *BranchesService + BuildVariables *BuildVariablesService + Builds *BuildsService + Commits *CommitsService + DeployKeys *DeployKeysService + Groups *GroupsService + Issues *IssuesService + Labels *LabelsService + MergeRequests *MergeRequestsService + Milestones *MilestonesService + Namespaces *NamespacesService + Notes *NotesService + NotificationSettings *NotificationSettingsService + Projects *ProjectsService + ProjectSnippets *ProjectSnippetsService + Pipelines *PipelinesService + Repositories *RepositoriesService + RepositoryFiles *RepositoryFilesService + Services *ServicesService + Session *SessionService + Settings *SettingsService + SystemHooks *SystemHooksService + Tags *TagsService + TimeStats *TimeStatsService + Users *UsersService +} + +// ListOptions specifies the optional parameters to various List methods that +// support pagination. +type ListOptions struct { + // For paginated result sets, page of results to retrieve. + Page int `url:"page,omitempty" json:"page,omitempty"` + + // For paginated result sets, the number of results to include per page. + PerPage int `url:"per_page,omitempty" json:"per_page,omitempty"` +} + +// NewClient returns a new GitLab API client. If a nil httpClient is +// provided, http.DefaultClient will be used. To use API methods which require +// authentication, provide a valid private token. +func NewClient(httpClient *http.Client, token string) *Client { + return newClient(httpClient, privateToken, token) +} + +// NewOAuthClient returns a new GitLab API client. If a nil httpClient is +// provided, http.DefaultClient will be used. To use API methods which require +// authentication, provide a valid oauth token. +func NewOAuthClient(httpClient *http.Client, token string) *Client { + return newClient(httpClient, oAuthToken, token) +} + +func newClient(httpClient *http.Client, tokenType tokenType, token string) *Client { + if httpClient == nil { + httpClient = http.DefaultClient + } + + c := &Client{client: httpClient, tokenType: tokenType, token: token, UserAgent: userAgent} + if err := c.SetBaseURL(defaultBaseURL); err != nil { + // should never happen since defaultBaseURL is our constant + panic(err) + } + + c.Branches = &BranchesService{client: c} + c.BuildVariables = &BuildVariablesService{client: c} + c.Builds = &BuildsService{client: c} + c.Commits = &CommitsService{client: c} + c.DeployKeys = &DeployKeysService{client: c} + c.Groups = &GroupsService{client: c} + c.Issues = &IssuesService{client: c} + c.Labels = &LabelsService{client: c} + c.MergeRequests = &MergeRequestsService{client: c} + c.Milestones = &MilestonesService{client: c} + c.Namespaces = &NamespacesService{client: c} + c.Notes = &NotesService{client: c} + c.NotificationSettings = &NotificationSettingsService{client: c} + c.Projects = &ProjectsService{client: c} + c.ProjectSnippets = &ProjectSnippetsService{client: c} + c.Pipelines = &PipelinesService{client: c} + c.Repositories = &RepositoriesService{client: c} + c.RepositoryFiles = &RepositoryFilesService{client: c} + c.Services = &ServicesService{client: c} + c.Session = &SessionService{client: c} + c.Settings = &SettingsService{client: c} + c.SystemHooks = &SystemHooksService{client: c} + c.Tags = &TagsService{client: c} + c.TimeStats = &TimeStatsService{client: c} + c.Users = &UsersService{client: c} + + return c +} + +// BaseURL return a copy of the baseURL. +func (c *Client) BaseURL() *url.URL { + u := *c.baseURL + return &u +} + +// SetBaseURL sets the base URL for API requests to a custom endpoint. urlStr +// should always be specified with a trailing slash. +func (c *Client) SetBaseURL(urlStr string) error { + // Make sure the given URL end with a slash + if !strings.HasSuffix(urlStr, "/") { + urlStr += "/" + } + + var err error + c.baseURL, err = url.Parse(urlStr) + return err +} + +// NewRequest creates an API request. A relative URL path can be provided in +// urlStr, in which case it is resolved relative to the base URL of the Client. +// Relative URL paths should always be specified without a preceding slash. If +// specified, the value pointed to by body is JSON encoded and included as the +// request body. +func (c *Client) NewRequest(method, path string, opt interface{}, options []OptionFunc) (*http.Request, error) { + u := *c.baseURL + // Set the encoded opaque data + u.Opaque = c.baseURL.Path + path + + if opt != nil { + q, err := query.Values(opt) + if err != nil { + return nil, err + } + u.RawQuery = q.Encode() + } + + req := &http.Request{ + Method: method, + URL: &u, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + Host: u.Host, + } + + for _, fn := range options { + if err := fn(req); err != nil { + return nil, err + } + } + + if method == "POST" || method == "PUT" { + bodyBytes, err := json.Marshal(opt) + if err != nil { + return nil, err + } + bodyReader := bytes.NewReader(bodyBytes) + + u.RawQuery = "" + req.Body = ioutil.NopCloser(bodyReader) + req.ContentLength = int64(bodyReader.Len()) + req.Header.Set("Content-Type", "application/json") + } + + req.Header.Set("Accept", "application/json") + + switch c.tokenType { + case privateToken: + req.Header.Set("PRIVATE-TOKEN", c.token) + case oAuthToken: + req.Header.Set("Authorization", "Bearer "+c.token) + } + + if c.UserAgent != "" { + req.Header.Set("User-Agent", c.UserAgent) + } + + return req, nil +} + +// Response is a GitLab API response. This wraps the standard http.Response +// returned from GitLab and provides convenient access to things like +// pagination links. +type Response struct { + *http.Response + + // These fields provide the page values for paginating through a set of + // results. Any or all of these may be set to the zero value for + // responses that are not part of a paginated set, or for which there + // are no additional pages. + + NextPage int + PrevPage int + FirstPage int + LastPage int +} + +// newResponse creats a new Response for the provided http.Response. +func newResponse(r *http.Response) *Response { + response := &Response{Response: r} + response.populatePageValues() + return response +} + +// populatePageValues parses the HTTP Link response headers and populates the +// various pagination link values in the Reponse. +func (r *Response) populatePageValues() { + if links, ok := r.Response.Header["Link"]; ok && len(links) > 0 { + for _, link := range strings.Split(links[0], ",") { + segments := strings.Split(strings.TrimSpace(link), ";") + + // link must at least have href and rel + if len(segments) < 2 { + continue + } + + // ensure href is properly formatted + if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") { + continue + } + + // try to pull out page parameter + url, err := url.Parse(segments[0][1 : len(segments[0])-1]) + if err != nil { + continue + } + page := url.Query().Get("page") + if page == "" { + continue + } + + for _, segment := range segments[1:] { + switch strings.TrimSpace(segment) { + case `rel="next"`: + r.NextPage, _ = strconv.Atoi(page) + case `rel="prev"`: + r.PrevPage, _ = strconv.Atoi(page) + case `rel="first"`: + r.FirstPage, _ = strconv.Atoi(page) + case `rel="last"`: + r.LastPage, _ = strconv.Atoi(page) + } + + } + } + } +} + +// Do sends an API request and returns the API response. The API response is +// JSON decoded and stored in the value pointed to by v, or returned as an +// error if an API error has occurred. If v implements the io.Writer +// interface, the raw response body will be written to v, without attempting to +// first decode it. +func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { + resp, err := c.client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + response := newResponse(resp) + + err = CheckResponse(resp) + if err != nil { + // even though there was an error, we still return the response + // in case the caller wants to inspect it further + return response, err + } + + if v != nil { + if w, ok := v.(io.Writer); ok { + _, err = io.Copy(w, resp.Body) + } else { + err = json.NewDecoder(resp.Body).Decode(v) + } + } + return response, err +} + +// Helper function to accept and format both the project ID or name as project +// identifier for all API calls. +func parseID(id interface{}) (string, error) { + switch v := id.(type) { + case int: + return strconv.Itoa(v), nil + case string: + return v, nil + default: + return "", fmt.Errorf("invalid ID type %#v, the ID must be an int or a string", id) + } +} + +// An ErrorResponse reports one or more errors caused by an API request. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/README.html#data-validation-and-error-reporting +type ErrorResponse struct { + Response *http.Response + Message string +} + +func (e *ErrorResponse) Error() string { + path, _ := url.QueryUnescape(e.Response.Request.URL.Opaque) + u := fmt.Sprintf("%s://%s%s", e.Response.Request.URL.Scheme, e.Response.Request.URL.Host, path) + return fmt.Sprintf("%s %s: %d %s", e.Response.Request.Method, u, e.Response.StatusCode, e.Message) +} + +// CheckResponse checks the API response for errors, and returns them if present. +func CheckResponse(r *http.Response) error { + switch r.StatusCode { + case 200, 201, 304: + return nil + } + + errorResponse := &ErrorResponse{Response: r} + data, err := ioutil.ReadAll(r.Body) + if err == nil && data != nil { + var raw interface{} + if err := json.Unmarshal(data, &raw); err != nil { + errorResponse.Message = "failed to parse unknown error format" + } + + errorResponse.Message = parseError(raw) + } + + return errorResponse +} + +// Format: +// { +// "message": { +// "": [ +// "", +// "", +// ... +// ], +// "": { +// "": [ +// "", +// "", +// ... +// ], +// } +// }, +// "error": "" +// } +func parseError(raw interface{}) string { + switch raw := raw.(type) { + case string: + return raw + + case []interface{}: + var errs []string + for _, v := range raw { + errs = append(errs, parseError(v)) + } + return fmt.Sprintf("[%s]", strings.Join(errs, ", ")) + + case map[string]interface{}: + var errs []string + for k, v := range raw { + errs = append(errs, fmt.Sprintf("{%s: %s}", k, parseError(v))) + } + sort.Strings(errs) + return fmt.Sprintf("%s", strings.Join(errs, ", ")) + + default: + return fmt.Sprintf("failed to parse unexpected error type: %T", raw) + } +} + +// OptionFunc can be passed to all API requests to make the API call as if you were +// another user, provided your private token is from an administrator account. +// +// GitLab docs: https://docs.gitlab.com/ce/api/README.html#sudo +type OptionFunc func(*http.Request) error + +// WithSudo takes either a username or user ID and sets the SUDO request header +func WithSudo(uid interface{}) OptionFunc { + return func(req *http.Request) error { + switch uid := uid.(type) { + case int: + req.Header.Set("SUDO", strconv.Itoa(uid)) + return nil + case string: + req.Header.Set("SUDO", uid) + return nil + default: + return fmt.Errorf("uid must be either a username or user ID") + } + } +} + +// WithContext runs the request with the provided context +func WithContext(ctx context.Context) OptionFunc { + return func(req *http.Request) error { + *req = *req.WithContext(ctx) + return nil + } +} + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { + p := new(bool) + *p = v + return p +} + +// Int is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it, but unlike Int32 +// its argument value is an int. +func Int(v int) *int { + p := new(int) + *p = v + return p +} + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { + p := new(string) + *p = v + return p +} + +// AccessLevel is a helper routine that allocates a new AccessLevelValue +// to store v and returns a pointer to it. +func AccessLevel(v AccessLevelValue) *AccessLevelValue { + p := new(AccessLevelValue) + *p = v + return p +} + +// NotificationLevel is a helper routine that allocates a new NotificationLevelValue +// to store v and returns a pointer to it. +func NotificationLevel(v NotificationLevelValue) *NotificationLevelValue { + p := new(NotificationLevelValue) + *p = v + return p +} + +// VisibilityLevel is a helper routine that allocates a new VisibilityLevelValue +// to store v and returns a pointer to it. +func VisibilityLevel(v VisibilityLevelValue) *VisibilityLevelValue { + p := new(VisibilityLevelValue) + *p = v + return p +} diff --git a/vendor/github.com/xanzy/go-gitlab/groups.go b/vendor/github.com/xanzy/go-gitlab/groups.go new file mode 100644 index 000000000..6e5e00187 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/groups.go @@ -0,0 +1,358 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "time" +) + +// GroupsService handles communication with the group related methods of +// the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html +type GroupsService struct { + client *Client +} + +// Group represents a GitLab group. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html +type Group struct { + ID int `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + Description string `json:"description"` + Projects []*Project `json:"projects"` + Statistics *StorageStatistics `json:"statistics"` +} + +// ListGroupsOptions represents the available ListGroups() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-project-groups +type ListGroupsOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` + Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` +} + +// ListGroups gets a list of groups. (As user: my groups, as admin: all groups) +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#list-project-groups +func (s *GroupsService) ListGroups(opt *ListGroupsOptions, options ...OptionFunc) ([]*Group, *Response, error) { + req, err := s.client.NewRequest("GET", "groups", opt, options) + if err != nil { + return nil, nil, err + } + + var g []*Group + resp, err := s.client.Do(req, &g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// GetGroup gets all details of a group. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#details-of-a-group +func (s *GroupsService) GetGroup(gid interface{}, options ...OptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s", group) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// CreateGroupOptions represents the available CreateGroup() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group +type CreateGroupOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + VisibilityLevel *VisibilityLevelValue `url:"visibility_level" json:"visibility_level,omitempty"` +} + +// CreateGroup creates a new project group. Available only for users who can +// create groups. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group +func (s *GroupsService) CreateGroup(opt *CreateGroupOptions, options ...OptionFunc) (*Group, *Response, error) { + req, err := s.client.NewRequest("POST", "groups", opt, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// TransferGroup transfers a project to the Group namespace. Available only +// for admin. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#transfer-project-to-group +func (s *GroupsService) TransferGroup(gid interface{}, project int, options ...OptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/projects/%d", group, project) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// DeleteGroup removes group with all projects inside. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#remove-group +func (s *GroupsService) DeleteGroup(gid interface{}, options ...OptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s", group) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SearchGroup get all groups that match your string in their name or path. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#search-for-group +func (s *GroupsService) SearchGroup(query string, options ...OptionFunc) ([]*Group, *Response, error) { + var q struct { + Search string `url:"search,omitempty" json:"search,omitempty"` + } + q.Search = query + + req, err := s.client.NewRequest("GET", "groups", &q, options) + if err != nil { + return nil, nil, err + } + + var g []*Group + resp, err := s.client.Do(req, &g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// GroupMember represents a GitLab group member. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html +type GroupMember struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + AccessLevel AccessLevelValue `json:"access_level"` +} + +// ListGroupMembersOptions represents the available ListGroupMembers() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#list-group-members +type ListGroupMembersOptions struct { + ListOptions +} + +// ListGroupMembers get a list of group members viewable by the authenticated +// user. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#list-group-members +func (s *GroupsService) ListGroupMembers(gid interface{}, opt *ListGroupMembersOptions, options ...OptionFunc) ([]*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members", group) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var g []*GroupMember + resp, err := s.client.Do(req, &g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// ListGroupProjectsOptions represents the available ListGroupProjects() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#list-a-group-s-projects +type ListGroupProjectsOptions struct { + ListOptions +} + +// ListGroupProjects get a list of group projects +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#list-a-group-s-projects +func (s *GroupsService) ListGroupProjects(gid interface{}, opt *ListGroupProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/projects", group) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// AddGroupMemberOptions represents the available AddGroupMember() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#add-group-member +type AddGroupMemberOptions struct { + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` +} + +// AddGroupMember adds a user to the list of group members. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#list-group-members +func (s *GroupsService) AddGroupMember(gid interface{}, opt *AddGroupMemberOptions, options ...OptionFunc) (*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members", group) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + g := new(GroupMember) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// UpdateGroupMemberOptions represents the available UpdateGroupMember() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#edit-group-team-member +type UpdateGroupMemberOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` +} + +// UpdateGroupMember updates a group team member to a specified access level. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#list-group-members +func (s *GroupsService) UpdateGroupMember(gid interface{}, user int, opt *UpdateGroupMemberOptions, options ...OptionFunc) (*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members/%d", group, user) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + g := new(GroupMember) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, err +} + +// RemoveGroupMember removes user from user team. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/groups.html#remove-user-from-user-team +func (s *GroupsService) RemoveGroupMember(gid interface{}, user int, options ...OptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/members/%d", group, user) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/issues.go b/vendor/github.com/xanzy/go-gitlab/issues.go new file mode 100644 index 000000000..0a286c203 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/issues.go @@ -0,0 +1,264 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "fmt" + "net/url" + "strings" + "time" +) + +// IssuesService handles communication with the issue related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html +type IssuesService struct { + client *Client +} + +// Issue represents a GitLab issue. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html +type Issue struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + Labels []string `json:"labels"` + Milestone *Milestone `json:"milestone"` + Assignee struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + } `json:"assignee"` + Author struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + } `json:"author"` + State string `json:"state"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` + Subscribed bool `json:"subscribed"` + UserNotesCount int `json:"user_notes_count"` + Confidential bool `json:"confidential"` + DueDate string `json:"due_date"` + WebURL string `json:"web_url"` +} + +func (i Issue) String() string { + return Stringify(i) +} + +// Labels is a custom type with specific marshaling characteristics. +type Labels []string + +// MarshalJSON implements the json.Marshaler interface. +func (l *Labels) MarshalJSON() ([]byte, error) { + return json.Marshal(strings.Join(*l, ",")) +} + +// ListIssuesOptions represents the available ListIssues() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues +type ListIssuesOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` + Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListIssues gets all issues created by authenticated user. This function +// takes pagination parameters page and per_page to restrict the list of issues. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues +func (s *IssuesService) ListIssues(opt *ListIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) { + req, err := s.client.NewRequest("GET", "issues", opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, err +} + +// ListProjectIssuesOptions represents the available ListProjectIssues() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues +type ListProjectIssuesOptions struct { + ListOptions + IID *int `url:"iid,omitempty" json:"iid,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListProjectIssues gets a list of project issues. This function accepts +// pagination parameters page and per_page to return the list of project issues. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-project-issues +func (s *IssuesService) ListProjectIssues(pid interface{}, opt *ListProjectIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, err +} + +// GetIssue gets a single project issue. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#single-issues +func (s *IssuesService) GetIssue(pid interface{}, issue int, options ...OptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, err +} + +// CreateIssueOptions represents the available CreateIssue() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues +type CreateIssueOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` +} + +// CreateIssue creates a new project issue. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues +func (s *IssuesService) CreateIssue(pid interface{}, opt *CreateIssueOptions, options ...OptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, err +} + +// UpdateIssueOptions represents the available UpdateIssue() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#edit-issues +type UpdateIssueOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` +} + +// UpdateIssue updates an existing project issue. This function is also used +// to mark an issue as closed. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#edit-issues +func (s *IssuesService) UpdateIssue(pid interface{}, issue int, opt *UpdateIssueOptions, options ...OptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, err +} + +// DeleteIssue deletes a single project issue. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#delete-an-issue +func (s *IssuesService) DeleteIssue(pid interface{}, issue int, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/labels.go b/vendor/github.com/xanzy/go-gitlab/labels.go new file mode 100644 index 000000000..8d571b7e8 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/labels.go @@ -0,0 +1,164 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" +) + +// LabelsService handles communication with the label related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html +type LabelsService struct { + client *Client +} + +// Label represents a GitLab label. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html +type Label struct { + Name string `json:"name"` + Color string `json:"color"` + Description string `json:"description"` + OpenIssuesCount int `json:"open_issues_count"` + ClosedIssuesCount int `json:"closed_issues_count"` + OpenMergeRequestsCount int `json:"open_merge_requests_count"` +} + +func (l Label) String() string { + return Stringify(l) +} + +// ListLabels gets all labels for given project. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels +func (s *LabelsService) ListLabels(pid interface{}, options ...OptionFunc) ([]*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var l []*Label + resp, err := s.client.Do(req, &l) + if err != nil { + return nil, resp, err + } + + return l, resp, err +} + +// CreateLabelOptions represents the available CreateLabel() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label +type CreateLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` +} + +// CreateLabel creates a new label for given repository with given name and +// color. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label +func (s *LabelsService) CreateLabel(pid interface{}, opt *CreateLabelOptions, options ...OptionFunc) (*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + l := new(Label) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, err +} + +// DeleteLabelOptions represents the available DeleteLabel() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label +type DeleteLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// DeleteLabel deletes a label given by its name. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label +func (s *LabelsService) DeleteLabel(pid interface{}, opt *DeleteLabelOptions, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project)) + + req, err := s.client.NewRequest("DELETE", u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UpdateLabelOptions represents the available UpdateLabel() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label +type UpdateLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` +} + +// UpdateLabel updates an existing label with new name or now color. At least +// one parameter is required, to update the label. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#edit-an-existing-label +func (s *LabelsService) UpdateLabel(pid interface{}, opt *UpdateLabelOptions, options ...OptionFunc) (*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + l := new(Label) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/merge_requests.go b/vendor/github.com/xanzy/go-gitlab/merge_requests.go new file mode 100644 index 000000000..1d154067b --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/merge_requests.go @@ -0,0 +1,333 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// MergeRequestsService handles communication with the merge requests related +// methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html +type MergeRequestsService struct { + client *Client +} + +// MergeRequest represents a GitLab merge request. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html +type MergeRequest struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + WorkInProgress bool `json:"work_in_progress"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + TargetBranch string `json:"target_branch"` + SourceBranch string `json:"source_branch"` + Upvotes int `json:"upvotes"` + Downvotes int `json:"downvotes"` + Author struct { + Name string `json:"name"` + Username string `json:"username"` + ID int `json:"id"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + } `json:"author"` + Assignee struct { + Name string `json:"name"` + Username string `json:"username"` + ID int `json:"id"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + } `json:"assignee"` + SourceProjectID int `json:"source_project_id"` + TargetProjectID int `json:"target_project_id"` + Labels []string `json:"labels"` + Milestone struct { + ID int `json:"id"` + Iid int `json:"iid"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + DueDate string `json:"due_date"` + } `json:"milestone"` + MergeWhenBuildSucceeds bool `json:"merge_when_build_succeeds"` + MergeStatus string `json:"merge_status"` + Subscribed bool `json:"subscribed"` + UserNotesCount int `json:"user_notes_count"` + SouldRemoveSourceBranch bool `json:"should_remove_source_branch"` + ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` + Changes []struct { + OldPath string `json:"old_path"` + NewPath string `json:"new_path"` + AMode string `json:"a_mode"` + BMode string `json:"b_mode"` + Diff string `json:"diff"` + NewFile bool `json:"new_file"` + RenamedFile bool `json:"renamed_file"` + DeletedFile bool `json:"deleted_file"` + } `json:"changes"` + WebURL string `json:"web_url"` +} + +func (m MergeRequest) String() string { + return Stringify(m) +} + +// ListMergeRequestsOptions represents the available ListMergeRequests() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests +type ListMergeRequestsOptions struct { + ListOptions + IID *int `url:"iid,omitempty" json:"iid,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListMergeRequests gets all merge requests for this project. The state +// parameter can be used to get only merge requests with a given state (opened, +// closed, or merged) or all of them (all). The pagination parameters page and +// per_page can be used to restrict the list of merge requests. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests +func (s *MergeRequestsService) ListMergeRequests(pid interface{}, opt *ListMergeRequestsOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*MergeRequest + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// GetMergeRequest shows information about a single merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr +func (s *MergeRequestsService) GetMergeRequest(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d", url.QueryEscape(project), mergeRequest) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// GetMergeRequestCommits gets a list of merge request commits. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-commits +func (s *MergeRequestsService) GetMergeRequestCommits(pid interface{}, mergeRequest int, options ...OptionFunc) ([]*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/commits", url.QueryEscape(project), mergeRequest) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var c []*Commit + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} + +// GetMergeRequestChanges shows information about the merge request including +// its files and changes. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-changes +func (s *MergeRequestsService) GetMergeRequestChanges(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/changes", url.QueryEscape(project), mergeRequest) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// CreateMergeRequestOptions represents the available CreateMergeRequest() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#create-mr +type CreateMergeRequestOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + SourceBranch *string `url:"source_branch,omitemtpy" json:"source_branch,omitemtpy"` + TargetBranch *string `url:"target_branch,omitemtpy" json:"target_branch,omitemtpy"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + TargetProjectID *int `url:"target_project_id,omitempty" json:"target_project_id,omitempty"` +} + +// CreateMergeRequest creates a new merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#create-mr +func (s *MergeRequestsService) CreateMergeRequest(pid interface{}, opt *CreateMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// UpdateMergeRequestOptions represents the available UpdateMergeRequest() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#update-mr +type UpdateMergeRequestOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + TargetBranch *string `url:"target_branch,omitemtpy" json:"target_branch,omitemtpy"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` +} + +// UpdateMergeRequest updates an existing project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#update-mr +func (s *MergeRequestsService) UpdateMergeRequest(pid interface{}, mergeRequest int, opt *UpdateMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d", url.QueryEscape(project), mergeRequest) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// AcceptMergeRequestOptions represents the available AcceptMergeRequest() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr +type AcceptMergeRequestOptions struct { + MergeCommitMessage *string `url:"merge_commit_message,omitempty" json:"merge_commit_message,omitempty"` + ShouldRemoveSourceBranch *bool `url:"should_remove_source_branch,omitempty" json:"should_remove_source_branch,omitempty"` + MergeWhenBuildSucceeds *bool `url:"merge_when_build_succeeds,omitempty" json:"merge_when_build_succeeds,omitempty"` + Sha *string `url:"sha,omitempty" json:"sha,omitempty"` +} + +// AcceptMergeRequest merges changes submitted with MR using this API. If merge +// success you get 200 OK. If it has some conflicts and can not be merged - you +// get 405 and error message 'Branch cannot be merged'. If merge request is +// already merged or closed - you get 405 and error message 'Method Not Allowed' +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr +func (s *MergeRequestsService) AcceptMergeRequest(pid interface{}, mergeRequest int, opt *AcceptMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/merge", url.QueryEscape(project), mergeRequest) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/milestones.go b/vendor/github.com/xanzy/go-gitlab/milestones.go new file mode 100644 index 000000000..eeaf9cce2 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/milestones.go @@ -0,0 +1,216 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// MilestonesService handles communication with the milestone related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html +type MilestonesService struct { + client *Client +} + +// Milestone represents a GitLab milestone. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html +type Milestone struct { + ID int `json:"id"` + Iid int `json:"iid"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + StartDate string `json:"start_date"` + DueDate string `json:"due_date"` + State string `json:"state"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` +} + +func (m Milestone) String() string { + return Stringify(m) +} + +// ListMilestonesOptions represents the available ListMilestones() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones +type ListMilestonesOptions struct { + ListOptions + IID *int `url:"iid,omitempty" json:"iid,omitempty"` +} + +// ListMilestones returns a list of project milestones. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones +func (s *MilestonesService) ListMilestones(pid interface{}, opt *ListMilestonesOptions, options ...OptionFunc) ([]*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*Milestone + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// GetMilestone gets a single project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#get-single-milestone +func (s *MilestonesService) GetMilestone(pid interface{}, milestone int, options ...OptionFunc) (*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d", url.QueryEscape(project), milestone) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(Milestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// CreateMilestoneOptions represents the available CreateMilestone() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone +type CreateMilestoneOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + StartDate *string `url:"start_date,omitempty" json:"start_date,omitempty"` + DueDate *string `url:"due_date,omitempty" json:"due_date,omitempty"` +} + +// CreateMilestone creates a new project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone +func (s *MilestonesService) CreateMilestone(pid interface{}, opt *CreateMilestoneOptions, options ...OptionFunc) (*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(Milestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// UpdateMilestoneOptions represents the available UpdateMilestone() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone +type UpdateMilestoneOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + StartDate *string `url:"start_date,omitempty" json:"start_date,omitempty"` + DueDate *string `url:"due_date,omitempty" json:"due_date,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` +} + +// UpdateMilestone updates an existing project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone +func (s *MilestonesService) UpdateMilestone(pid interface{}, milestone int, opt *UpdateMilestoneOptions, options ...OptionFunc) (*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d", url.QueryEscape(project), milestone) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(Milestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, err +} + +// GetMilestoneIssuesOptions represents the available GetMilestoneIssues() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone +type GetMilestoneIssuesOptions struct { + ListOptions +} + +// GetMilestoneIssues gets all issues assigned to a single project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone +func (s *MilestonesService) GetMilestoneIssues(pid interface{}, milestone int, opt *GetMilestoneIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d/issues", url.QueryEscape(project), milestone) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/namespaces.go b/vendor/github.com/xanzy/go-gitlab/namespaces.go new file mode 100644 index 000000000..d4b5e4508 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/namespaces.go @@ -0,0 +1,89 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +// NamespacesService handles communication with the namespace related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html +type NamespacesService struct { + client *Client +} + +// Namespace represents a GitLab namespace. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html +type Namespace struct { + ID int `json:"id"` + Path string `json:"path"` + Kind string `json:"kind"` +} + +func (n Namespace) String() string { + return Stringify(n) +} + +// ListNamespacesOptions represents the available ListNamespaces() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces +type ListNamespacesOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` +} + +// ListNamespaces gets a list of projects accessible by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces +func (s *NamespacesService) ListNamespaces(opt *ListNamespacesOptions, options ...OptionFunc) ([]*Namespace, *Response, error) { + req, err := s.client.NewRequest("GET", "namespaces", opt, options) + if err != nil { + return nil, nil, err + } + + var n []*Namespace + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// SearchNamespace gets all namespaces that match your string in their name +// or path. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/namespaces.html#search-for-namespace +func (s *NamespacesService) SearchNamespace(query string, options ...OptionFunc) ([]*Namespace, *Response, error) { + var q struct { + Search string `url:"search,omitempty" json:"search,omitempty"` + } + q.Search = query + + req, err := s.client.NewRequest("GET", "namespaces", &q, options) + if err != nil { + return nil, nil, err + } + + var n []*Namespace + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/notes.go b/vendor/github.com/xanzy/go-gitlab/notes.go new file mode 100644 index 000000000..c1836c2b8 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/notes.go @@ -0,0 +1,418 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// NotesService handles communication with the notes related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html +type NotesService struct { + client *Client +} + +// Note represents a GitLab note. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html +type Note struct { + ID int `json:"id"` + Body string `json:"body"` + Attachment string `json:"attachment"` + Title string `json:"title"` + FileName string `json:"file_name"` + Author struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + } `json:"author"` + ExpiresAt *time.Time `json:"expires_at"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` +} + +func (n Note) String() string { + return Stringify(n) +} + +// ListIssueNotesOptions represents the available ListIssueNotes() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes +type ListIssueNotesOptions struct { + ListOptions +} + +// ListIssueNotes gets a list of all notes for a single issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes +func (s *NotesService) ListIssueNotes(pid interface{}, issue int, opt *ListIssueNotesOptions, options ...OptionFunc) ([]*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var n []*Note + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// GetIssueNote returns a single note for a specific project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#get-single-issue-note +func (s *NotesService) GetIssueNote(pid interface{}, issue int, note int, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", url.QueryEscape(project), issue, note) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// CreateIssueNoteOptions represents the available CreateIssueNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note +type CreateIssueNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// CreateIssueNote creates a new note to a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note +func (s *NotesService) CreateIssueNote(pid interface{}, issue int, opt *CreateIssueNoteOptions, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// UpdateIssueNoteOptions represents the available UpdateIssueNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note +type UpdateIssueNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// UpdateIssueNote modifies existing note of an issue. +// +// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note +func (s *NotesService) UpdateIssueNote(pid interface{}, issue int, note int, opt *UpdateIssueNoteOptions, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", url.QueryEscape(project), issue, note) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// ListSnippetNotes gets a list of all notes for a single snippet. Snippet +// notes are comments users can post to a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#list-all-snippet-notes +func (s *NotesService) ListSnippetNotes(pid interface{}, snippet int, options ...OptionFunc) ([]*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes", url.QueryEscape(project), snippet) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var n []*Note + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// GetSnippetNote returns a single note for a given snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#get-single-snippet-note +func (s *NotesService) GetSnippetNote(pid interface{}, snippet int, note int, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", url.QueryEscape(project), snippet, note) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// CreateSnippetNoteOptions represents the available CreateSnippetNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note +type CreateSnippetNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// CreateSnippetNote creates a new note for a single snippet. Snippet notes are +// comments users can post to a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note +func (s *NotesService) CreateSnippetNote(pid interface{}, snippet int, opt *CreateSnippetNoteOptions, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes", url.QueryEscape(project), snippet) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// UpdateSnippetNoteOptions represents the available UpdateSnippetNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note +type UpdateSnippetNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// UpdateSnippetNote modifies existing note of a snippet. +// +// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note +func (s *NotesService) UpdateSnippetNote(pid interface{}, snippet int, note int, opt *UpdateSnippetNoteOptions, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", url.QueryEscape(project), snippet, note) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// ListMergeRequestNotes gets a list of all notes for a single merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#list-all-merge-request-notes +func (s *NotesService) ListMergeRequestNotes(pid interface{}, mergeRequest int, options ...OptionFunc) ([]*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", url.QueryEscape(project), mergeRequest) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var n []*Note + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// GetMergeRequestNote returns a single note for a given merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#get-single-merge-request-note +func (s *NotesService) GetMergeRequestNote(pid interface{}, mergeRequest int, note int, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/notes/%d", url.QueryEscape(project), mergeRequest, note) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// CreateMergeRequestNoteOptions represents the available +// CreateMergeRequestNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note +type CreateMergeRequestNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// CreateMergeRequestNote creates a new note for a single merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note +func (s *NotesService) CreateMergeRequestNote(pid interface{}, mergeRequest int, opt *CreateMergeRequestNoteOptions, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", url.QueryEscape(project), mergeRequest) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} + +// UpdateMergeRequestNoteOptions represents the available +// UpdateMergeRequestNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note +type UpdateMergeRequestNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// UpdateMergeRequestNote modifies existing note of a merge request. +// +// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note +func (s *NotesService) UpdateMergeRequestNote(pid interface{}, mergeRequest int, note int, opt *UpdateMergeRequestNoteOptions, options ...OptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/merge_requests/%d/notes/%d", url.QueryEscape(project), mergeRequest, note) + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/notifications.go b/vendor/github.com/xanzy/go-gitlab/notifications.go new file mode 100644 index 000000000..04424c293 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/notifications.go @@ -0,0 +1,214 @@ +package gitlab + +import ( + "errors" + "fmt" + "net/url" +) + +// NotificationSettingsService handles communication with the notification settings +// related methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/notification_settings.html +type NotificationSettingsService struct { + client *Client +} + +// NotificationSettings represents the Gitlab notification setting. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings +type NotificationSettings struct { + Level NotificationLevelValue `json:"level"` + NotificationEmail string `json:"notification_email"` + Events *NotificationEvents `json:"events"` +} + +// NotificationEvents represents the avialable notification setting events. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings +type NotificationEvents struct { + CloseIssue bool `json:"close_issue"` + CloseMergeRequest bool `json:"close_merge_request"` + FailedPipeline bool `json:"failed_pipeline"` + MergeMergeRequest bool `json:"merge_merge_request"` + NewIssue bool `json:"new_issue"` + NewMergeRequest bool `json:"new_merge_request"` + NewNote bool `json:"new_note"` + ReassignIssue bool `json:"reassign_issue"` + ReassignMergeRequest bool `json:"reassign_merge_request"` + ReopenIssue bool `json:"reopen_issue"` + ReopenMergeRequest bool `json:"reopen_merge_request"` + SuccessPipeline bool `json:"success_pipeline"` +} + +func (ns NotificationSettings) String() string { + return Stringify(ns) +} + +// GetGlobalSettings returns current notification settings and email address. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#global-notification-settings +func (s *NotificationSettingsService) GetGlobalSettings(options ...OptionFunc) (*NotificationSettings, *Response, error) { + u := "notification_settings" + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, err +} + +// NotificationSettingsOptions represents the available options that can be passed +// to the API when updating the notification settings. +type NotificationSettingsOptions struct { + Level *NotificationLevelValue `url:"level,omitempty" json:"level,omitempty"` + NotificationEmail *string `url:"notification_email,omitempty" json:"notification_email,omitempty"` + CloseIssue *bool `url:"close_issue,omitempty" json:"close_issue,omitempty"` + CloseMergeRequest *bool `url:"close_merge_request,omitempty" json:"close_merge_request,omitempty"` + FailedPipeline *bool `url:"failed_pipeline,omitempty" json:"failed_pipeline,omitempty"` + MergeMergeRequest *bool `url:"merge_merge_request,omitempty" json:"merge_merge_request,omitempty"` + NewIssue *bool `url:"new_issue,omitempty" json:"new_issue,omitempty"` + NewMergeRequest *bool `url:"new_merge_request,omitempty" json:"new_merge_request,omitempty"` + NewNote *bool `url:"new_note,omitempty" json:"new_note,omitempty"` + ReassignIssue *bool `url:"reassign_issue,omitempty" json:"reassign_issue,omitempty"` + ReassignMergeRequest *bool `url:"reassign_merge_request,omitempty" json:"reassign_merge_request,omitempty"` + ReopenIssue *bool `url:"reopen_issue,omitempty" json:"reopen_issue,omitempty"` + ReopenMergeRequest *bool `url:"reopen_merge_request,omitempty" json:"reopen_merge_request,omitempty"` + SuccessPipeline *bool `url:"success_pipeline,omitempty" json:"success_pipeline,omitempty"` +} + +// UpdateGlobalSettings updates current notification settings and email address. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#update-global-notification-settings +func (s *NotificationSettingsService) UpdateGlobalSettings(opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) { + if opt.Level != nil && *opt.Level == GlobalNotificationLevel { + return nil, nil, errors.New( + "notification level 'global' is not valid for global notification settings") + } + + u := "notification_settings" + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, err +} + +// GetSettingsForGroup returns current group notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings +func (s *NotificationSettingsService) GetSettingsForGroup(gid interface{}, options ...OptionFunc) (*NotificationSettings, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/notification_settings", url.QueryEscape(group)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, err +} + +// GetSettingsForProject returns current project notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings +func (s *NotificationSettingsService) GetSettingsForProject(pid interface{}, options ...OptionFunc) (*NotificationSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/notification_settings", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, err +} + +// UpdateSettingsForGroup updates current group notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings +func (s *NotificationSettingsService) UpdateSettingsForGroup(gid interface{}, opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/notification_settings", url.QueryEscape(group)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, err +} + +// UpdateSettingsForProject updates current project notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings +func (s *NotificationSettingsService) UpdateSettingsForProject(pid interface{}, opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/notification_settings", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/pipelines.go b/vendor/github.com/xanzy/go-gitlab/pipelines.go new file mode 100644 index 000000000..4ade3fce9 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/pipelines.go @@ -0,0 +1,191 @@ +// +// Copyright 2017, Igor Varavko +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// PipelinesService handles communication with the repositories related +// methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html +type PipelinesService struct { + client *Client +} + +// Pipeline represents a GitLab pipeline. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html +type Pipeline struct { + ID int `json:"id"` + Status string `json:"status"` + Ref string `json:"ref"` + Sha string `json:"sha"` + BeforeSha string `json:"before_sha"` + Tag bool `json:"tag"` + YamlErrors string `json:"yaml_errors"` + User struct { + Name string `json:"name"` + Username string `json:"username"` + ID int `json:"id"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + CommittedAt *time.Time `json:"committed_at"` + Duration int `json:"duration"` + Coverage string `json:"coverage"` +} + +func (i Pipeline) String() string { + return Stringify(i) +} + +// ListProjectPipelines gets a list of project piplines. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#list-project-pipelines +func (s *PipelinesService) ListProjectPipelines(pid interface{}, options ...OptionFunc) ([]*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var p []*Pipeline + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + return p, resp, err +} + +// GetPipeline gets a single project pipeline. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#get-a-single-pipeline +func (s *PipelinesService) GetPipeline(pid interface{}, pipeline int, options ...OptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d", url.QueryEscape(project), pipeline) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// CreatePipelineOptions represents the available CreatePipeline() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline +type CreatePipelineOptions struct { + Ref *string `url:"ref,omitempty" json:"ref"` +} + +// CreatePipeline creates a new project pipeline. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline +func (s *PipelinesService) CreatePipeline(pid interface{}, opt *CreatePipelineOptions, options ...OptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// RetryPipelineBuild retries failed builds in a pipeline +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/pipelines.html#retry-failed-builds-in-a-pipeline +func (s *PipelinesService) RetryPipelineBuild(pid interface{}, pipelineID int, options ...OptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/retry", project, pipelineID) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// CancelPipelineBuild cancels a pipeline builds +// +// GitLab API docs: +//https://docs.gitlab.com/ce/api/pipelines.html#cancel-a-pipelines-builds +func (s *PipelinesService) CancelPipelineBuild(pid interface{}, pipelineID int, options ...OptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/cancel", project, pipelineID) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/project_snippets.go b/vendor/github.com/xanzy/go-gitlab/project_snippets.go new file mode 100644 index 000000000..65dab67be --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/project_snippets.go @@ -0,0 +1,232 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "net/url" + "time" +) + +// ProjectSnippetsService handles communication with the project snippets +// related methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html +type ProjectSnippetsService struct { + client *Client +} + +// Snippet represents a GitLab project snippet. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html +type Snippet struct { + ID int `json:"id"` + Title string `json:"title"` + FileName string `json:"file_name"` + Author struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + } `json:"author"` + ExpiresAt *time.Time `json:"expires_at"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` +} + +func (s Snippet) String() string { + return Stringify(s) +} + +// ListSnippetsOptions represents the available ListSnippets() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets +type ListSnippetsOptions struct { + ListOptions +} + +// ListSnippets gets a list of project snippets. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets +func (s *ProjectSnippetsService) ListSnippets(pid interface{}, opt *ListSnippetsOptions, options ...OptionFunc) ([]*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Snippet + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, err +} + +// GetSnippet gets a single project snippet +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/project_snippets.html#single-snippet +func (s *ProjectSnippetsService) GetSnippet(pid interface{}, snippet int, options ...OptionFunc) (*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, err +} + +// CreateSnippetOptions represents the available CreateSnippet() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet +type CreateSnippetOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` + Code *string `url:"code,omitempty" json:"code,omitempty"` + VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"` +} + +// CreateSnippet creates a new project snippet. The user must have permission +// to create new snippets. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet +func (s *ProjectSnippetsService) CreateSnippet(pid interface{}, opt *CreateSnippetOptions, options ...OptionFunc) (*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, err +} + +// UpdateSnippetOptions represents the available UpdateSnippet() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet +type UpdateSnippetOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` + Code *string `url:"code,omitempty" json:"code,omitempty"` + VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"` +} + +// UpdateSnippet updates an existing project snippet. The user must have +// permission to change an existing snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet +func (s *ProjectSnippetsService) UpdateSnippet(pid interface{}, snippet int, opt *UpdateSnippetOptions, options ...OptionFunc) (*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, err +} + +// DeleteSnippet deletes an existing project snippet. This is an idempotent +// function and deleting a non-existent snippet still returns a 200 OK status +// code. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/project_snippets.html#delete-snippet +func (s *ProjectSnippetsService) DeleteSnippet(pid interface{}, snippet int, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SnippetContent returns the raw project snippet as plain text. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/project_snippets.html#snippet-content +func (s *ProjectSnippetsService) SnippetContent(pid interface{}, snippet int, options ...OptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/raw", url.QueryEscape(project), snippet) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/projects.go b/vendor/github.com/xanzy/go-gitlab/projects.go new file mode 100644 index 000000000..9abc6b141 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/projects.go @@ -0,0 +1,981 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// ProjectsService handles communication with the repositories related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html +type ProjectsService struct { + client *Client +} + +// Project represents a GitLab project. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html +type Project struct { + ID int `json:"id"` + Description string `json:"description"` + DefaultBranch string `json:"default_branch"` + Public bool `json:"public"` + VisibilityLevel VisibilityLevelValue `json:"visibility_level"` + SSHURLToRepo string `json:"ssh_url_to_repo"` + HTTPURLToRepo string `json:"http_url_to_repo"` + WebURL string `json:"web_url"` + TagList []string `json:"tag_list"` + Owner *User `json:"owner"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + IssuesEnabled bool `json:"issues_enabled"` + OpenIssuesCount int `json:"open_issues_count"` + MergeRequestsEnabled bool `json:"merge_requests_enabled"` + ApprovalsBeforeMerge int `json:"approvals_before_merge"` + BuildsEnabled bool `json:"builds_enabled"` + WikiEnabled bool `json:"wiki_enabled"` + SnippetsEnabled bool `json:"snippets_enabled"` + ContainerRegistryEnabled bool `json:"container_registry_enabled"` + CreatedAt *time.Time `json:"created_at,omitempty"` + LastActivityAt *time.Time `json:"last_activity_at,omitempty"` + CreatorID int `json:"creator_id"` + Namespace *ProjectNamespace `json:"namespace"` + Permissions *Permissions `json:"permissions"` + Archived bool `json:"archived"` + AvatarURL string `json:"avatar_url"` + SharedRunnersEnabled bool `json:"shared_runners_enabled"` + ForksCount int `json:"forks_count"` + StarCount int `json:"star_count"` + RunnersToken string `json:"runners_token"` + PublicBuilds bool `json:"public_builds"` + OnlyAllowMergeIfBuildSucceeds bool `json:"only_allow_merge_if_build_succeeds"` + OnlyAllowMergeIfAllDiscussionsAreResolved bool `json:"only_allow_merge_if_all_discussions_are_resolved"` + LFSEnabled bool `json:"lfs_enabled"` + RequestAccessEnabled bool `json:"request_access_enabled"` + SharedWithGroups []struct { + GroupID int `json:"group_id"` + GroupName string `json:"group_name"` + GroupAccessLevel int `json:"group_access_level"` + } `json:"shared_with_groups"` + Statistics *ProjectStatistics `json:"statistics"` +} + +// Repository represents a repository. +type Repository struct { + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` +} + +// ProjectNamespace represents a project namespace. +type ProjectNamespace struct { + CreatedAt *time.Time `json:"created_at"` + Description string `json:"description"` + ID int `json:"id"` + Name string `json:"name"` + OwnerID int `json:"owner_id"` + Path string `json:"path"` + UpdatedAt *time.Time `json:"updated_at"` +} + +// StorageStatistics represents a statistics record for a group or project. +type StorageStatistics struct { + StorageSize int64 `json:"storage_size"` + RepositorySize int64 `json:"repository_size"` + LfsObjectsSize int64 `json:"lfs_objects_size"` + BuildArtifactsSize int64 `json:"build_artifacts_size"` +} + +// ProjectStatistics represents a statistics record for a project. +type ProjectStatistics struct { + StorageStatistics + CommitCount int `json:"commit_count"` +} + +// Permissions represents premissions. +type Permissions struct { + ProjectAccess *ProjectAccess `json:"project_access"` + GroupAccess *GroupAccess `json:"group_access"` +} + +// ProjectAccess represents project access. +type ProjectAccess struct { + AccessLevel AccessLevelValue `json:"access_level"` + NotificationLevel NotificationLevelValue `json:"notification_level"` +} + +// GroupAccess represents group access. +type GroupAccess struct { + AccessLevel AccessLevelValue `json:"access_level"` + NotificationLevel NotificationLevelValue `json:"notification_level"` +} + +func (s Project) String() string { + return Stringify(s) +} + +// ListProjectsOptions represents the available ListProjects() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-projects +type ListProjectsOptions struct { + ListOptions + Archived *bool `url:"archived,omitempty" json:"archived,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + Simple *bool `url:"simple,omitempty" json:"simple,omitempty"` + Visibility *string `url:"visibility,omitempty" json:"visibility,omitempty"` + Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` +} + +// ListProjects gets a list of projects accessible by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-projects +func (s *ProjectsService) ListProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) { + req, err := s.client.NewRequest("GET", "projects", opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// ListOwnedProjects gets a list of projects which are owned by the +// authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-owned-projects +func (s *ProjectsService) ListOwnedProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) { + req, err := s.client.NewRequest("GET", "projects/owned", opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// ListStarredProjects gets a list of projects which are starred by the +// authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-starred-projects +func (s *ProjectsService) ListStarredProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) { + req, err := s.client.NewRequest("GET", "projects/starred", opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// ListAllProjects gets a list of all GitLab projects (admin only). +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-all-projects +func (s *ProjectsService) ListAllProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) { + req, err := s.client.NewRequest("GET", "projects/all", opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// GetProject gets a specific project, identified by project ID or +// NAMESPACE/PROJECT_NAME, which is owned by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#get-single-project +func (s *ProjectsService) GetProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// SearchProjectsOptions represents the available SearchProjects() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#search-for-projects-by-name +type SearchProjectsOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// SearchProjects searches for projects by name which are accessible to the +// authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#search-for-projects-by-name +func (s *ProjectsService) SearchProjects(query string, opt *SearchProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) { + u := fmt.Sprintf("projects/search/%s", query) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// ProjectEvent represents a GitLab project event. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#get-project-events +type ProjectEvent struct { + Title interface{} `json:"title"` + ProjectID int `json:"project_id"` + ActionName string `json:"action_name"` + TargetID interface{} `json:"target_id"` + TargetType interface{} `json:"target_type"` + AuthorID int `json:"author_id"` + AuthorUsername string `json:"author_username"` + Data struct { + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + Repository *Repository `json:"repository"` + Commits []*Commit `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` + } `json:"data"` + TargetTitle interface{} `json:"target_title"` +} + +func (s ProjectEvent) String() string { + return Stringify(s) +} + +// GetProjectEventsOptions represents the available GetProjectEvents() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#get-project-events +type GetProjectEventsOptions struct { + ListOptions +} + +// GetProjectEvents gets the events for the specified project. Sorted from +// newest to latest. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#get-project-events +func (s *ProjectsService) GetProjectEvents(pid interface{}, opt *GetProjectEventsOptions, options ...OptionFunc) ([]*ProjectEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/events", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*ProjectEvent + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// CreateProjectOptions represents the available CreateProjects() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#create-project +type CreateProjectOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + NamespaceID *int `url:"namespace_id,omitempty" json:"namespace_id,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` + MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"` + BuildsEnabled *bool `url:"builds_enabled,omitempty" json:"builds_enabled,omitempty"` + WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"` + SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"` + ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"` + SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` + Public *bool `url:"public,omitempty" json:"public,omitempty"` + VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"` + ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` + PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` + OnlyAllowMergeIfBuildSucceeds *bool `url:"only_allow_merge_if_build_succeeds,omitempty" json:"only_allow_merge_if_build_succeeds,omitempty"` + LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` + RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` +} + +// CreateProject creates a new project owned by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#create-project +func (s *ProjectsService) CreateProject(opt *CreateProjectOptions, options ...OptionFunc) (*Project, *Response, error) { + req, err := s.client.NewRequest("POST", "projects", opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// CreateProjectForUserOptions represents the available CreateProjectForUser() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#create-project-for-user +type CreateProjectForUserOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` + IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` + MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"` + WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"` + SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"` + Public *bool `url:"public,omitempty" json:"public,omitempty"` + VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"` + ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` +} + +// CreateProjectForUser creates a new project owned by the specified user. +// Available only for admins. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#create-project-for-user +func (s *ProjectsService) CreateProjectForUser(user int, opt *CreateProjectForUserOptions, options ...OptionFunc) (*Project, *Response, error) { + u := fmt.Sprintf("projects/user/%d", user) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// EditProjectOptions represents the available EditProject() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#edit-project +type EditProjectOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` + IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` + MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"` + ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` + BuildsEnabled *bool `url:"builds_enabled,omitempty" json:"builds_enabled,omitempty"` + WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"` + SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"` + ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"` + SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` + Public *bool `url:"public,omitempty" json:"public,omitempty"` + VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"` + ImportURL *bool `url:"import_url,omitempty" json:"import_url,omitempty"` + PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` + OnlyAllowMergeIfBuildSucceeds *bool `url:"only_allow_merge_if_build_succeeds,omitempty" json:"only_allow_merge_if_build_succeeds,omitempty"` + OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"` + LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` + RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` +} + +// EditProject updates an existing project. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#edit-project +func (s *ProjectsService) EditProject(pid interface{}, opt *EditProjectOptions, options ...OptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// ForkProject forks a project into the user namespace of the authenticated +// user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#fork-project +func (s *ProjectsService) ForkProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/fork/%s", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// DeleteProject removes a project including all associated resources +// (issues, merge requests etc.) +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#remove-project +func (s *ProjectsService) DeleteProject(pid interface{}, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s", url.QueryEscape(project)) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ProjectMember represents a project member. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-project-team-members +type ProjectMember struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + AccessLevel AccessLevelValue `json:"access_level"` +} + +// ListProjectMembersOptions represents the available ListProjectMembers() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-project-team-members +type ListProjectMembersOptions struct { + ListOptions + Query *string `url:"query,omitempty" json:"query,omitempty"` +} + +// ListProjectMembers gets a list of a project's team members. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-project-team-members +func (s *ProjectsService) ListProjectMembers(pid interface{}, opt *ListProjectMembersOptions, options ...OptionFunc) ([]*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var pm []*ProjectMember + resp, err := s.client.Do(req, &pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, err +} + +// GetProjectMember gets a project team member. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#get-project-team-member +func (s *ProjectsService) GetProjectMember(pid interface{}, user int, options ...OptionFunc) (*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMember) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, err +} + +// AddProjectMemberOptions represents the available AddProjectMember() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#add-project-team-member +type AddProjectMemberOptions struct { + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` +} + +// AddProjectMember adds a user to a project team. This is an idempotent +// method and can be called multiple times with the same parameters. Adding +// team membership to a user that is already a member does not affect the +// existing membership. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#add-project-team-member +func (s *ProjectsService) AddProjectMember(pid interface{}, opt *AddProjectMemberOptions, options ...OptionFunc) (*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMember) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, err +} + +// EditProjectMemberOptions represents the available EditProjectMember() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#edit-project-team-member +type EditProjectMemberOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` +} + +// EditProjectMember updates a project team member to a specified access level.. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#edit-project-team-member +func (s *ProjectsService) EditProjectMember(pid interface{}, user int, opt *EditProjectMemberOptions, options ...OptionFunc) (*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMember) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, err +} + +// DeleteProjectMember removes a user from a project team. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#remove-project-team-member +func (s *ProjectsService) DeleteProjectMember(pid interface{}, user int, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ProjectHook represents a project hook. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-project-hooks +type ProjectHook struct { + ID int `json:"id"` + URL string `json:"url"` + ProjectID int `json:"project_id"` + PushEvents bool `json:"push_events"` + IssuesEvents bool `json:"issues_events"` + MergeRequestsEvents bool `json:"merge_requests_events"` + TagPushEvents bool `json:"tag_push_events"` + NoteEvents bool `json:"note_events"` + BuildEvents bool `json:"build_events"` + PipelineEvents bool `json:"pipeline_events"` + WikiPageEvents bool `json:"wiki_page_events"` + EnableSSLVerification bool `json:"enable_ssl_verification"` + CreatedAt *time.Time `json:"created_at"` +} + +// ListProjectHooksOptions represents the available ListProjectHooks() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-project-hooks +type ListProjectHooksOptions struct { + ListOptions +} + +// ListProjectHooks gets a list of project hooks. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#list-project-hooks +func (s *ProjectsService) ListProjectHooks(pid interface{}, opt *ListProjectHooksOptions, options ...OptionFunc) ([]*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var ph []*ProjectHook + resp, err := s.client.Do(req, &ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, err +} + +// GetProjectHook gets a specific hook for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#get-project-hook +func (s *ProjectsService) GetProjectHook(pid interface{}, hook int, options ...OptionFunc) (*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d", url.QueryEscape(project), hook) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + ph := new(ProjectHook) + resp, err := s.client.Do(req, ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, err +} + +// AddProjectHookOptions represents the available AddProjectHook() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#add-project-hook +type AddProjectHookOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + BuildEvents *bool `url:"build_events,omitempty" json:"build_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + Token *string `url:"token,omitempty" json:"token,omitempty"` +} + +// AddProjectHook adds a hook to a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#add-project-hook +func (s *ProjectsService) AddProjectHook(pid interface{}, opt *AddProjectHookOptions, options ...OptionFunc) (*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + ph := new(ProjectHook) + resp, err := s.client.Do(req, ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, err +} + +// EditProjectHookOptions represents the available EditProjectHook() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#edit-project-hook +type EditProjectHookOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + BuildEvents *bool `url:"build_events,omitempty" json:"build_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + Token *string `url:"token,omitempty" json:"token,omitempty"` +} + +// EditProjectHook edits a hook for a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#edit-project-hook +func (s *ProjectsService) EditProjectHook(pid interface{}, hook int, opt *EditProjectHookOptions, options ...OptionFunc) (*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d", url.QueryEscape(project), hook) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + ph := new(ProjectHook) + resp, err := s.client.Do(req, ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, err +} + +// DeleteProjectHook removes a hook from a project. This is an idempotent +// method and can be called multiple times. Either the hook is available or not. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#delete-project-hook +func (s *ProjectsService) DeleteProjectHook(pid interface{}, hook int, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d", url.QueryEscape(project), hook) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ProjectForkRelation represents a project fork relationship. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#admin-fork-relation +type ProjectForkRelation struct { + ID int `json:"id"` + ForkedToProjectID int `json:"forked_to_project_id"` + ForkedFromProjectID int `json:"forked_from_project_id"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` +} + +// CreateProjectForkRelation creates a forked from/to relation between +// existing projects. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#create-a-forked-fromto-relation-between-existing-projects. +func (s *ProjectsService) CreateProjectForkRelation(pid int, fork int, options ...OptionFunc) (*ProjectForkRelation, *Response, error) { + u := fmt.Sprintf("projects/%d/fork/%d", pid, fork) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + pfr := new(ProjectForkRelation) + resp, err := s.client.Do(req, pfr) + if err != nil { + return nil, resp, err + } + + return pfr, resp, err +} + +// DeleteProjectForkRelation deletes an existing forked from relationship. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#delete-an-existing-forked-from-relationship +func (s *ProjectsService) DeleteProjectForkRelation(pid int, options ...OptionFunc) (*Response, error) { + u := fmt.Sprintf("projects/%d/fork", pid) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ArchiveProject archives the project if the user is either admin or the +// project owner of this project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#archive-a-project +func (s *ProjectsService) ArchiveProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/archive", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} + +// UnarchiveProject unarchives the project if the user is either admin or +// the project owner of this project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/projects.html#unarchive-a-project +func (s *ProjectsService) UnarchiveProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/unarchive", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/repositories.go b/vendor/github.com/xanzy/go-gitlab/repositories.go new file mode 100644 index 000000000..aa1052ff6 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/repositories.go @@ -0,0 +1,259 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "net/url" +) + +// RepositoriesService handles communication with the repositories related +// methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html +type RepositoriesService struct { + client *Client +} + +// TreeNode represents a GitLab repository file or directory. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html +type TreeNode struct { + ID string `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Mode string `json:"mode"` +} + +func (t TreeNode) String() string { + return Stringify(t) +} + +// ListTreeOptions represents the available ListTree() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#list-repository-tree +type ListTreeOptions struct { + Path *string `url:"path,omitempty" json:"path,omitempty"` + RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"` +} + +// ListTree gets a list of repository files and directories in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#list-repository-tree +func (s *RepositoriesService) ListTree(pid interface{}, opt *ListTreeOptions, options ...OptionFunc) ([]*TreeNode, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tree", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var t []*TreeNode + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// RawFileContentOptions represents the available RawFileContent() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#raw-file-content +type RawFileContentOptions struct { + FilePath *string `url:"filepath,omitempty" json:"filepath,omitempty"` +} + +// RawFileContent gets the raw file contents for a file by commit SHA and path +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#raw-file-content +func (s *RepositoriesService) RawFileContent(pid interface{}, sha string, opt *RawFileContentOptions, options ...OptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/blobs/%s", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// RawBlobContent gets the raw file contents for a blob by blob SHA. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#raw-blob-content +func (s *RepositoriesService) RawBlobContent(pid interface{}, sha string, options ...OptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/raw_blobs/%s", url.QueryEscape(project), sha) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// ArchiveOptions represents the available Archive() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#get-file-archive +type ArchiveOptions struct { + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` +} + +// Archive gets an archive of the repository. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#get-file-archive +func (s *RepositoriesService) Archive(pid interface{}, opt *ArchiveOptions, options ...OptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/archive", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// Compare represents the result of a comparison of branches, tags or commits. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits +type Compare struct { + Commit *Commit `json:"commit"` + Commits []*Commit `json:"commits"` + Diffs []*Diff `json:"diffs"` + CompareTimeout bool `json:"compare_timeout"` + CompareSameRef bool `json:"compare_same_ref"` +} + +func (c Compare) String() string { + return Stringify(c) +} + +// CompareOptions represents the available Compare() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits +type CompareOptions struct { + From *string `url:"from,omitempty" json:"from,omitempty"` + To *string `url:"to,omitempty" json:"to,omitempty"` +} + +// Compare compares branches, tags or commits. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits +func (s *RepositoriesService) Compare(pid interface{}, opt *CompareOptions, options ...OptionFunc) (*Compare, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/compare", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(Compare) + resp, err := s.client.Do(req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} + +// Contributor represents a GitLap contributor. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributer +type Contributor struct { + Name string `json:"name,omitempty"` + Email string `json:"email,omitempty"` + Commits int `json:"commits,omitempty"` + Additions int `json:"additions,omitempty"` + Deletions int `json:"deletions,omitempty"` +} + +func (c Contributor) String() string { + return Stringify(c) +} + +// Contributors gets the repository contributors list. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributer +func (s *RepositoriesService) Contributors(pid interface{}, options ...OptionFunc) ([]*Contributor, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/contributors", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var c []*Contributor + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/repository_files.go b/vendor/github.com/xanzy/go-gitlab/repository_files.go new file mode 100644 index 000000000..21e5f65cf --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/repository_files.go @@ -0,0 +1,210 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" +) + +// RepositoryFilesService handles communication with the repository files +// related methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html +type RepositoryFilesService struct { + client *Client +} + +// File represents a GitLab repository file. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html +type File struct { + FileName string `json:"file_name"` + FilePath string `json:"file_path"` + Size int `json:"size"` + Encoding string `json:"encoding"` + Content string `json:"content"` + Ref string `json:"ref"` + BlobID string `json:"blob_id"` + CommitID string `json:"commit_id"` +} + +func (r File) String() string { + return Stringify(r) +} + +// GetFileOptions represents the available GetFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-respository +type GetFileOptions struct { + FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// GetFile allows you to receive information about a file in repository like +// name, size, content. Note that file content is Base64 encoded. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-respository +func (s *RepositoryFilesService) GetFile(pid interface{}, opt *GetFileOptions, options ...OptionFunc) (*File, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, opt, options) + if err != nil { + return nil, nil, err + } + + f := new(File) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, err +} + +// FileInfo represents file details of a GitLab repository file. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html +type FileInfo struct { + FilePath string `json:"file_path"` + BranchName string `json:"branch_name"` +} + +func (r FileInfo) String() string { + return Stringify(r) +} + +// CreateFileOptions represents the available CreateFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository +type CreateFileOptions struct { + FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` + BranchName *string `url:"branch_name,omitempty" json:"branch_name,omitempty"` + Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` +} + +// CreateFile creates a new file in a repository. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository +func (s *RepositoryFilesService) CreateFile(pid interface{}, opt *CreateFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + f := new(FileInfo) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, err +} + +// UpdateFileOptions represents the available UpdateFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository +type UpdateFileOptions struct { + FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` + BranchName *string `url:"branch_name,omitempty" json:"branch_name,omitempty"` + Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` +} + +// UpdateFile updates an existing file in a repository +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository +func (s *RepositoryFilesService) UpdateFile(pid interface{}, opt *UpdateFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + f := new(FileInfo) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, err +} + +// DeleteFileOptions represents the available DeleteFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository +type DeleteFileOptions struct { + FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` + BranchName *string `url:"branch_name,omitempty" json:"branch_name,omitempty"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` +} + +// DeleteFile deletes an existing file in a repository +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository +func (s *RepositoryFilesService) DeleteFile(pid interface{}, opt *DeleteFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project)) + + req, err := s.client.NewRequest("DELETE", u, opt, options) + if err != nil { + return nil, nil, err + } + + f := new(FileInfo) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/services.go b/vendor/github.com/xanzy/go-gitlab/services.go new file mode 100644 index 000000000..dbcdf84ab --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/services.go @@ -0,0 +1,279 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" + "time" +) + +// ServicesService handles communication with the services related methods of +// the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/services.html +type ServicesService struct { + client *Client +} + +// Service represents a GitLab service. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/services.html +type Service struct { + ID *int `json:"id"` + Title *string `json:"title"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"created_at"` + Active *bool `json:"active"` + PushEvents *bool `json:"push_events"` + IssuesEvents *bool `json:"issues_events"` + MergeRequestsEvents *bool `json:"merge_requests_events"` + TagPushEvents *bool `json:"tag_push_events"` + NoteEvents *bool `json:"note_events"` +} + +// SetGitLabCIServiceOptions represents the available SetGitLabCIService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service +type SetGitLabCIServiceOptions struct { + Token *string `url:"token,omitempty" json:"token,omitempty"` + ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"` +} + +// SetGitLabCIService sets GitLab CI service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service +func (s *ServicesService) SetGitLabCIService(pid interface{}, opt *SetGitLabCIServiceOptions, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/gitlab-ci", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteGitLabCIService deletes GitLab CI service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#delete-gitlab-ci-service +func (s *ServicesService) DeleteGitLabCIService(pid interface{}, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/gitlab-ci", url.QueryEscape(project)) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SetHipChatServiceOptions represents the available SetHipChatService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service +type SetHipChatServiceOptions struct { + Token *string `url:"token,omitempty" json:"token,omitempty" ` + Room *string `url:"room,omitempty" json:"room,omitempty"` +} + +// SetHipChatService sets HipChat service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service +func (s *ServicesService) SetHipChatService(pid interface{}, opt *SetHipChatServiceOptions, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/hipchat", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteHipChatService deletes HipChat service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#delete-hipchat-service +func (s *ServicesService) DeleteHipChatService(pid interface{}, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/hipchat", url.QueryEscape(project)) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SetDroneCIServiceOptions represents the available SetDroneCIService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service +type SetDroneCIServiceOptions struct { + Token *string `url:"token" json:"token" ` + DroneURL *string `url:"drone_url" json:"drone_url"` + EnableSSLVerification *string `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` +} + +// SetDroneCIService sets Drone CI service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service +func (s *ServicesService) SetDroneCIService(pid interface{}, opt *SetDroneCIServiceOptions, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/drone-ci", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteDroneCIService deletes Drone CI service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#delete-drone-ci-service +func (s *ServicesService) DeleteDroneCIService(pid interface{}, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/drone-ci", url.QueryEscape(project)) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DroneCIServiceProperties represents Drone CI specific properties. +type DroneCIServiceProperties struct { + Token *string `url:"token" json:"token"` + DroneURL *string `url:"drone_url" json:"drone_url"` + EnableSSLVerification *string `url:"enable_ssl_verification" json:"enable_ssl_verification"` +} + +// DroneCIService represents Drone CI service settings. +type DroneCIService struct { + Service + Properties *DroneCIServiceProperties `json:"properties"` +} + +// GetDroneCIService gets Drone CI service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#get-drone-ci-service-settings +func (s *ServicesService) GetDroneCIService(pid interface{}, options ...OptionFunc) (*DroneCIService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/drone-ci", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + opt := new(DroneCIService) + resp, err := s.client.Do(req, opt) + if err != nil { + return nil, resp, err + } + + return opt, resp, err +} + +// SetSlackServiceOptions represents the available SetSlackService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#edit-slack-service +type SetSlackServiceOptions struct { + WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty" ` + Username *string `url:"username,omitempty" json:"username,omitempty" ` + Channel *string `url:"channel,omitempty" json:"channel,omitempty"` +} + +// SetSlackService sets Slack service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#edit-slack-service +func (s *ServicesService) SetSlackService(pid interface{}, opt *SetSlackServiceOptions, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project)) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteSlackService deletes Slack service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/services.html#delete-slack-service +func (s *ServicesService) DeleteSlackService(pid interface{}, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project)) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/session.go b/vendor/github.com/xanzy/go-gitlab/session.go new file mode 100644 index 000000000..571483cd3 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/session.go @@ -0,0 +1,78 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "time" + +// SessionService handles communication with the session related methods of +// the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/session.html +type SessionService struct { + client *Client +} + +// Session represents a GitLab session. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/session.html#session +type Session struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + PrivateToken string `json:"private_token"` + Blocked bool `json:"blocked"` + CreatedAt *time.Time `json:"created_at"` + Bio interface{} `json:"bio"` + Skype string `json:"skype"` + Linkedin string `json:"linkedin"` + Twitter string `json:"twitter"` + WebsiteURL string `json:"website_url"` + DarkScheme bool `json:"dark_scheme"` + ThemeID int `json:"theme_id"` + IsAdmin bool `json:"is_admin"` + CanCreateGroup bool `json:"can_create_group"` + CanCreateTeam bool `json:"can_create_team"` + CanCreateProject bool `json:"can_create_project"` +} + +// GetSessionOptions represents the available Session() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/session.html#session +type GetSessionOptions struct { + Login *string `url:"login,omitempty" json:"login,omitempty"` + Email *string `url:"email,omitempty" json:"email,omitempty"` + Password *string `url:"password,omitempty" json:"password,omitempty"` +} + +// GetSession logs in to get private token. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/session.html#session +func (s *SessionService) GetSession(opt *GetSessionOptions, options ...OptionFunc) (*Session, *Response, error) { + req, err := s.client.NewRequest("POST", "session", opt, options) + if err != nil { + return nil, nil, err + } + + session := new(Session) + resp, err := s.client.Do(req, session) + if err != nil { + return nil, resp, err + } + + return session, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/settings.go b/vendor/github.com/xanzy/go-gitlab/settings.go new file mode 100644 index 000000000..41e9c9dab --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/settings.go @@ -0,0 +1,117 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "time" + +// SettingsService handles communication with the application SettingsService +// related methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/settings.html +type SettingsService struct { + client *Client +} + +// Settings represents the GitLab application settings. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/settings.html +type Settings struct { + ID int `json:"id"` + DefaultProjectsLimit int `json:"default_projects_limit"` + SignupEnabled bool `json:"signup_enabled"` + SigninEnabled bool `json:"signin_enabled"` + GravatarEnabled bool `json:"gravatar_enabled"` + SignInText string `json:"sign_in_text"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + HomePageURL string `json:"home_page_url"` + DefaultBranchProtection int `json:"default_branch_protection"` + TwitterSharingEnabled bool `json:"twitter_sharing_enabled"` + RestrictedVisibilityLevels []VisibilityLevelValue `json:"restricted_visibility_levels"` + MaxAttachmentSize int `json:"max_attachment_size"` + SessionExpireDelay int `json:"session_expire_delay"` + DefaultProjectVisibility int `json:"default_project_visibility"` + DefaultSnippetVisibility int `json:"default_snippet_visibility"` + RestrictedSignupDomains []string `json:"restricted_signup_domains"` + UserOauthApplications bool `json:"user_oauth_applications"` + AfterSignOutPath string `json:"after_sign_out_path"` +} + +func (s Settings) String() string { + return Stringify(s) +} + +// GetSettings gets the current application settings. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/settings.html#get-current-application.settings +func (s *SettingsService) GetSettings(options ...OptionFunc) (*Settings, *Response, error) { + req, err := s.client.NewRequest("GET", "application/settings", nil, options) + if err != nil { + return nil, nil, err + } + + as := new(Settings) + resp, err := s.client.Do(req, as) + if err != nil { + return nil, resp, err + } + + return as, resp, err +} + +// UpdateSettingsOptions represents the available UpdateSettings() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/settings.html#change-application.settings +type UpdateSettingsOptions struct { + DefaultProjectsLimit *int `url:"default_projects_limit,omitempty" json:"default_projects_limit,omitempty"` + SignupEnabled *bool `url:"signup_enabled,omitempty" json:"signup_enabled,omitempty"` + SigninEnabled *bool `url:"signin_enabled,omitempty" json:"signin_enabled,omitempty"` + GravatarEnabled *bool `url:"gravatar_enabled,omitempty" json:"gravatar_enabled,omitempty"` + SignInText *string `url:"sign_in_text,omitempty" json:"sign_in_text,omitempty"` + HomePageURL *string `url:"home_page_url,omitempty" json:"home_page_url,omitempty"` + DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"` + TwitterSharingEnabled *bool `url:"twitter_sharing_enabled,omitempty" json:"twitter_sharing_enabled,omitempty"` + RestrictedVisibilityLevels []VisibilityLevelValue `url:"restricted_visibility_levels,omitempty" json:"restricted_visibility_levels,omitempty"` + MaxAttachmentSize *int `url:"max_attachment_size,omitempty" json:"max_attachment_size,omitempty"` + SessionExpireDelay *int `url:"session_expire_delay,omitempty" json:"session_expire_delay,omitempty"` + DefaultProjectVisibility *int `url:"default_project_visibility,omitempty" json:"default_project_visibility,omitempty"` + DefaultSnippetVisibility *int `url:"default_snippet_visibility,omitempty" json:"default_snippet_visibility,omitempty"` + RestrictedSignupDomains []string `url:"restricted_signup_domains,omitempty" json:"restricted_signup_domains,omitempty"` + UserOauthApplications *bool `url:"user_oauth_applications,omitempty" json:"user_oauth_applications,omitempty"` + AfterSignOutPath *string `url:"after_sign_out_path,omitempty" json:"after_sign_out_path,omitempty"` +} + +// UpdateSettings updates the application settings. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/settings.html#change-application.settings +func (s *SettingsService) UpdateSettings(opt *UpdateSettingsOptions, options ...OptionFunc) (*Settings, *Response, error) { + req, err := s.client.NewRequest("PUT", "application/settings", opt, options) + if err != nil { + return nil, nil, err + } + + as := new(Settings) + resp, err := s.client.Do(req, as) + if err != nil { + return nil, resp, err + } + + return as, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/strings.go b/vendor/github.com/xanzy/go-gitlab/strings.go new file mode 100644 index 000000000..d0e7679b3 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/strings.go @@ -0,0 +1,94 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + + "reflect" +) + +// Stringify attempts to create a reasonable string representation of types in +// the GitHub library. It does things like resolve pointers to their values +// and omits struct fields with nil values. +func Stringify(message interface{}) string { + var buf bytes.Buffer + v := reflect.ValueOf(message) + stringifyValue(&buf, v) + return buf.String() +} + +// stringifyValue was heavily inspired by the goprotobuf library. +func stringifyValue(buf *bytes.Buffer, val reflect.Value) { + if val.Kind() == reflect.Ptr && val.IsNil() { + buf.WriteString("") + return + } + + v := reflect.Indirect(val) + + switch v.Kind() { + case reflect.String: + fmt.Fprintf(buf, `"%s"`, v) + case reflect.Slice: + buf.WriteByte('[') + for i := 0; i < v.Len(); i++ { + if i > 0 { + buf.WriteByte(' ') + } + + stringifyValue(buf, v.Index(i)) + } + + buf.WriteByte(']') + return + case reflect.Struct: + if v.Type().Name() != "" { + buf.WriteString(v.Type().String()) + } + + buf.WriteByte('{') + + var sep bool + for i := 0; i < v.NumField(); i++ { + fv := v.Field(i) + if fv.Kind() == reflect.Ptr && fv.IsNil() { + continue + } + if fv.Kind() == reflect.Slice && fv.IsNil() { + continue + } + + if sep { + buf.WriteString(", ") + } else { + sep = true + } + + buf.WriteString(v.Type().Field(i).Name) + buf.WriteByte(':') + stringifyValue(buf, fv) + } + + buf.WriteByte('}') + default: + if v.CanInterface() { + fmt.Fprint(buf, v.Interface()) + } + } +} diff --git a/vendor/github.com/xanzy/go-gitlab/system_hooks.go b/vendor/github.com/xanzy/go-gitlab/system_hooks.go new file mode 100644 index 000000000..20277a9af --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/system_hooks.go @@ -0,0 +1,143 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "time" +) + +// SystemHooksService handles communication with the system hooks related +// methods of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html +type SystemHooksService struct { + client *Client +} + +// Hook represents a GitLap system hook. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html +type Hook struct { + ID int `json:"id"` + URL string `json:"url"` + CreatedAt *time.Time `json:"created_at"` +} + +func (h Hook) String() string { + return Stringify(h) +} + +// ListHooks gets a list of system hooks. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/system_hooks.html#list-system-hooks +func (s *SystemHooksService) ListHooks(options ...OptionFunc) ([]*Hook, *Response, error) { + req, err := s.client.NewRequest("GET", "hooks", nil, options) + if err != nil { + return nil, nil, err + } + + var h []*Hook + resp, err := s.client.Do(req, &h) + if err != nil { + return nil, resp, err + } + + return h, resp, err +} + +// AddHookOptions represents the available AddHook() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook +type AddHookOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` +} + +// AddHook adds a new system hook hook. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook +func (s *SystemHooksService) AddHook(opt *AddHookOptions, options ...OptionFunc) (*Hook, *Response, error) { + req, err := s.client.NewRequest("POST", "hooks", opt, options) + if err != nil { + return nil, nil, err + } + + h := new(Hook) + resp, err := s.client.Do(req, h) + if err != nil { + return nil, resp, err + } + + return h, resp, err +} + +// HookEvent represents an event triggert by a GitLab system hook. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html +type HookEvent struct { + EventName string `json:"event_name"` + Name string `json:"name"` + Path string `json:"path"` + ProjectID int `json:"project_id"` + OwnerName string `json:"owner_name"` + OwnerEmail string `json:"owner_email"` +} + +func (h HookEvent) String() string { + return Stringify(h) +} + +// TestHook tests a system hook. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/system_hooks.html#test-system-hook +func (s *SystemHooksService) TestHook(hook int, options ...OptionFunc) (*HookEvent, *Response, error) { + u := fmt.Sprintf("hooks/%d", hook) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + h := new(HookEvent) + resp, err := s.client.Do(req, h) + if err != nil { + return nil, resp, err + } + + return h, resp, err +} + +// DeleteHook deletes a system hook. This is an idempotent API function and +// returns 200 OK even if the hook is not available. If the hook is deleted it +// is also returned as JSON. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/system_hooks.html#delete-system-hook +func (s *SystemHooksService) DeleteHook(hook int, options ...OptionFunc) (*Response, error) { + u := fmt.Sprintf("hooks/%d", hook) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/tags.go b/vendor/github.com/xanzy/go-gitlab/tags.go new file mode 100644 index 000000000..196f6d454 --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/tags.go @@ -0,0 +1,149 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/url" +) + +// TagsService handles communication with the tags related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html +type TagsService struct { + client *Client +} + +// Tag represents a GitLab tag. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html +type Tag struct { + Commit *Commit `json:"commit"` + Name string `json:"name"` + Message string `json:"message"` +} + +func (r Tag) String() string { + return Stringify(r) +} + +// ListTags gets a list of tags from a project, sorted by name in reverse +// alphabetical order. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/tags.html#list-project-repository-tags +func (s *TagsService) ListTags(pid interface{}, options ...OptionFunc) ([]*Tag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags", url.QueryEscape(project)) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var t []*Tag + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// GetTag a specific repository tag determined by its name. It returns 200 together +// with the tag information if the tag exists. It returns 404 if the tag does not exist. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/tags.html#get-a-single-repository-tag +func (s *TagsService) GetTag(pid interface{}, tag string, options ...OptionFunc) (*Tag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), tag) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var t *Tag + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// CreateTagOptions represents the available CreateTag() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/tags.html#create-a-new-tag +type CreateTagOptions struct { + TagName *string `url:"tag_name,omitempty" json:"tag_name,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Message *string `url:"message,omitempty" json:"message,omitempty"` +} + +// CreateTag creates a new tag in the repository that points to the supplied ref. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/tags.html#create-a-new-tag +func (s *TagsService) CreateTag(pid interface{}, opt *CreateTagOptions, options ...OptionFunc) (*Tag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags", url.QueryEscape(project)) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(Tag) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// DeleteTag deletes a tag of a repository with given name. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/tags.html#delete-a-tag +func (s *TagsService) DeleteTag(pid interface{}, tag string, options ...OptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), tag) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/time_stats.go b/vendor/github.com/xanzy/go-gitlab/time_stats.go new file mode 100644 index 000000000..c4a4ad40f --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/time_stats.go @@ -0,0 +1,171 @@ +package gitlab + +import ( + "fmt" + "net/url" +) + +// TimeStatsService handles communication with the time tracking related +// methods of the GitLab API. +// +// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html +type TimeStatsService struct { + client *Client +} + +// TimeStats represents the time estimates and time spent for an issue. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html +type TimeStats struct { + HumanTimeEstimate string `json:"human_time_estimate"` + HumanTotalTimeSpent string `json:"human_total_time_spent"` + TimeEstimate int `json:"time_estimate"` + TotalTimeSpent int `json:"total_time_spent"` +} + +func (t TimeStats) String() string { + return Stringify(t) +} + +// SetTimeEstimateOptions represents the available SetTimeEstimate() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/issues.html#set-a-time-estimate-for-an-issue +type SetTimeEstimateOptions struct { + Duration *string `url:"duration,omitempty" json:"duration,omitempty"` +} + +// SetTimeEstimate sets the time estimate for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/issues.html#set-a-time-estimate-for-an-issue +func (s *TimeStatsService) SetTimeEstimate(pid interface{}, issue int, opt *SetTimeEstimateOptions, options ...OptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/time_estimate", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// ResetTimeEstimate resets the time estimate for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/issues.html#reset-the-time-estimate-for-an-issue +func (s *TimeStatsService) ResetTimeEstimate(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/reset_time_estimate", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// AddSpentTimeOptions represents the available AddSpentTime() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/issues.html#add-spent-time-for-an-issue +type AddSpentTimeOptions struct { + Duration *string `url:"duration,omitempty" json:"duration,omitempty"` +} + +// AddSpentTime adds spent time for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/issues.html#add-spent-time-for-an-issue +func (s *TimeStatsService) AddSpentTime(pid interface{}, issue int, opt *AddSpentTimeOptions, options ...OptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/add_spent_time", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// ResetSpentTime resets the spent time for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/issues.html#reset-spent-time-for-an-issue +func (s *TimeStatsService) ResetSpentTime(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/reset_spent_time", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("POST", u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} + +// GetTimeSpent gets the spent time for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/issues.html#get-time-tracking-stats +func (s *TimeStatsService) GetTimeSpent(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/time_stats", url.QueryEscape(project), issue) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, err +} diff --git a/vendor/github.com/xanzy/go-gitlab/users.go b/vendor/github.com/xanzy/go-gitlab/users.go new file mode 100644 index 000000000..ba955a82f --- /dev/null +++ b/vendor/github.com/xanzy/go-gitlab/users.go @@ -0,0 +1,584 @@ +// +// Copyright 2015, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "errors" + "fmt" + "time" +) + +// UsersService handles communication with the user related methods of +// the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html +type UsersService struct { + client *Client +} + +// User represents a GitLab user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html +type User struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + Bio string `json:"bio"` + Skype string `json:"skype"` + Linkedin string `json:"linkedin"` + Twitter string `json:"twitter"` + WebsiteURL string `json:"website_url"` + ExternUID string `json:"extern_uid"` + Provider string `json:"provider"` + ThemeID int `json:"theme_id"` + ColorSchemeID int `json:"color_scheme_id"` + IsAdmin bool `json:"is_admin"` + AvatarURL string `json:"avatar_url"` + CanCreateGroup bool `json:"can_create_group"` + CanCreateProject bool `json:"can_create_project"` + ProjectsLimit int `json:"projects_limit"` + CurrentSignInAt *time.Time `json:"current_sign_in_at"` + LastSignInAt *time.Time `json:"last_sign_in_at"` + TwoFactorEnabled bool `json:"two_factor_enabled"` + Identities []*UserIdentity `json:"identities"` +} + +// UserIdentity represents a user identity +type UserIdentity struct { + Provider string `json:"provider"` + ExternUID string `json:"extern_uid"` +} + +// ListUsersOptions represents the available ListUsers() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-users +type ListUsersOptions struct { + ListOptions + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` +} + +// ListUsers gets a list of users. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-users +func (s *UsersService) ListUsers(opt *ListUsersOptions, options ...OptionFunc) ([]*User, *Response, error) { + req, err := s.client.NewRequest("GET", "users", opt, options) + if err != nil { + return nil, nil, err + } + + var usr []*User + resp, err := s.client.Do(req, &usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, err +} + +// GetUser gets a single user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-user +func (s *UsersService) GetUser(user int, options ...OptionFunc) (*User, *Response, error) { + u := fmt.Sprintf("users/%d", user) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, err +} + +// CreateUserOptions represents the available CreateUser() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-creation +type CreateUserOptions struct { + Email *string `url:"email,omitempty" json:"email,omitempty"` + Password *string `url:"password,omitempty" json:"password,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Skype *string `url:"skype,omitempty" json:"skype,omitempty"` + Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` + Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` + WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` + ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` + ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` + Provider *string `url:"provider,omitempty" json:"provider,omitempty"` + Bio *string `url:"bio,omitempty" json:"bio,omitempty"` + Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` + CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` + Confirm *bool `url:"confirm,omitempty" json:"confirm,omitempty"` +} + +// CreateUser creates a new user. Note only administrators can create new users. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-creation +func (s *UsersService) CreateUser(opt *CreateUserOptions, options ...OptionFunc) (*User, *Response, error) { + req, err := s.client.NewRequest("POST", "users", opt, options) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, err +} + +// ModifyUserOptions represents the available ModifyUser() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-modification +type ModifyUserOptions struct { + Email *string `url:"email,omitempty" json:"email,omitempty"` + Password *string `url:"password,omitempty" json:"password,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Skype *string `url:"skype,omitempty" json:"skype,omitempty"` + Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` + Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` + WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` + ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` + ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` + Provider *string `url:"provider,omitempty" json:"provider,omitempty"` + Bio *string `url:"bio,omitempty" json:"bio,omitempty"` + Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` + CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` +} + +// ModifyUser modifies an existing user. Only administrators can change attributes +// of a user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-modification +func (s *UsersService) ModifyUser(user int, opt *ModifyUserOptions, options ...OptionFunc) (*User, *Response, error) { + u := fmt.Sprintf("users/%d", user) + + req, err := s.client.NewRequest("PUT", u, opt, options) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, err +} + +// DeleteUser deletes a user. Available only for administrators. This is an +// idempotent function, calling this function for a non-existent user id still +// returns a status code 200 OK. The JSON response differs if the user was +// actually deleted or not. In the former the user is returned and in the +// latter not. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-deletion +func (s *UsersService) DeleteUser(user int, options ...OptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d", user) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// CurrentUser gets currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#current-user +func (s *UsersService) CurrentUser(options ...OptionFunc) (*User, *Response, error) { + req, err := s.client.NewRequest("GET", "user", nil, options) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, err +} + +// SSHKey represents a SSH key. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-ssh-keys +type SSHKey struct { + ID int `json:"id"` + Title string `json:"title"` + Key string `json:"key"` + CreatedAt *time.Time `json:"created_at"` +} + +// ListSSHKeys gets a list of currently authenticated user's SSH keys. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-ssh-keys +func (s *UsersService) ListSSHKeys(options ...OptionFunc) ([]*SSHKey, *Response, error) { + req, err := s.client.NewRequest("GET", "user/keys", nil, options) + if err != nil { + return nil, nil, err + } + + var k []*SSHKey + resp, err := s.client.Do(req, &k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// ListSSHKeysForUser gets a list of a specified user's SSH keys. Available +// only for admin +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/users.html#list-ssh-keys-for-user +func (s *UsersService) ListSSHKeysForUser(user int, options ...OptionFunc) ([]*SSHKey, *Response, error) { + u := fmt.Sprintf("users/%d/keys", user) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var k []*SSHKey + resp, err := s.client.Do(req, &k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// GetSSHKey gets a single key. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-ssh-key +func (s *UsersService) GetSSHKey(kid int, options ...OptionFunc) (*SSHKey, *Response, error) { + u := fmt.Sprintf("user/keys/%d", kid) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(SSHKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// AddSSHKeyOptions represents the available AddSSHKey() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#add-ssh-key +type AddSSHKeyOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Key *string `url:"key,omitempty" json:"key,omitempty"` +} + +// AddSSHKey creates a new key owned by the currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-ssh-key +func (s *UsersService) AddSSHKey(opt *AddSSHKeyOptions, options ...OptionFunc) (*SSHKey, *Response, error) { + req, err := s.client.NewRequest("POST", "user/keys", opt, options) + if err != nil { + return nil, nil, err + } + + k := new(SSHKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// AddSSHKeyForUser creates new key owned by specified user. Available only for +// admin. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-ssh-key-for-user +func (s *UsersService) AddSSHKeyForUser(user int, opt *AddSSHKeyOptions, options ...OptionFunc) (*SSHKey, *Response, error) { + u := fmt.Sprintf("users/%d/keys", user) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + k := new(SSHKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, err +} + +// DeleteSSHKey deletes key owned by currently authenticated user. This is an +// idempotent function and calling it on a key that is already deleted or not +// available results in 200 OK. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/users.html#delete-ssh-key-for-current-owner +func (s *UsersService) DeleteSSHKey(kid int, options ...OptionFunc) (*Response, error) { + u := fmt.Sprintf("user/keys/%d", kid) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteSSHKeyForUser deletes key owned by a specified user. Available only +// for admin. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/users.html#delete-ssh-key-for-given-user +func (s *UsersService) DeleteSSHKeyForUser(user int, kid int, options ...OptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d/keys/%d", user, kid) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// BlockUser blocks the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#block-user +func (s *UsersService) BlockUser(user int, options ...OptionFunc) error { + u := fmt.Sprintf("users/%d/block", user) + + req, err := s.client.NewRequest("PUT", u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil { + return err + } + + switch resp.StatusCode { + case 200: + return nil + case 403: + return errors.New("Cannot block a user that is already blocked by LDAP synchronization") + case 404: + return errors.New("User does not exists") + default: + return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode) + } +} + +// UnblockUser unblocks the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#unblock-user +func (s *UsersService) UnblockUser(user int, options ...OptionFunc) error { + u := fmt.Sprintf("users/%d/unblock", user) + + req, err := s.client.NewRequest("PUT", u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil { + return err + } + + switch resp.StatusCode { + case 200: + return nil + case 403: + return errors.New("Cannot unblock a user that is blocked by LDAP synchronization") + case 404: + return errors.New("User does not exists") + default: + return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode) + } +} + +// Email represents an Email. +// +// GitLab API docs: https://doc.gitlab.com/ce/api/users.html#list-emails +type Email struct { + ID int `json:"id"` + Email string `json:"email"` +} + +// ListEmails gets a list of currently authenticated user's Emails. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-emails +func (s *UsersService) ListEmails(options ...OptionFunc) ([]*Email, *Response, error) { + req, err := s.client.NewRequest("GET", "user/emails", nil, options) + if err != nil { + return nil, nil, err + } + + var e []*Email + resp, err := s.client.Do(req, &e) + if err != nil { + return nil, resp, err + } + + return e, resp, err +} + +// ListEmailsForUser gets a list of a specified user's Emails. Available +// only for admin +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/users.html#list-emails-for-user +func (s *UsersService) ListEmailsForUser(uid int, options ...OptionFunc) ([]*Email, *Response, error) { + u := fmt.Sprintf("users/%d/emails", uid) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + var e []*Email + resp, err := s.client.Do(req, &e) + if err != nil { + return nil, resp, err + } + + return e, resp, err +} + +// GetEmail gets a single email. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-email +func (s *UsersService) GetEmail(eid int, options ...OptionFunc) (*Email, *Response, error) { + u := fmt.Sprintf("user/emails/%d", eid) + + req, err := s.client.NewRequest("GET", u, nil, options) + if err != nil { + return nil, nil, err + } + + e := new(Email) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, err +} + +// AddEmailOptions represents the available AddEmail() options. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#add-email +type AddEmailOptions struct { + Email *string `url:"email,omitempty" json:"email,omitempty"` +} + +// AddEmail creates a new email owned by the currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-email +func (s *UsersService) AddEmail(opt *AddEmailOptions, options ...OptionFunc) (*Email, *Response, error) { + req, err := s.client.NewRequest("POST", "user/emails", opt, options) + if err != nil { + return nil, nil, err + } + + e := new(Email) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, err +} + +// AddEmailForUser creates new email owned by specified user. Available only for +// admin. +// +// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-email-for-user +func (s *UsersService) AddEmailForUser(uid int, opt *AddEmailOptions, options ...OptionFunc) (*Email, *Response, error) { + u := fmt.Sprintf("users/%d/emails", uid) + + req, err := s.client.NewRequest("POST", u, opt, options) + if err != nil { + return nil, nil, err + } + + e := new(Email) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, err +} + +// DeleteEmail deletes email owned by currently authenticated user. This is an +// idempotent function and calling it on a key that is already deleted or not +// available results in 200 OK. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/users.html#delete-email-for-current-owner +func (s *UsersService) DeleteEmail(eid int, options ...OptionFunc) (*Response, error) { + u := fmt.Sprintf("user/emails/%d", eid) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteEmailForUser deletes email owned by a specified user. Available only +// for admin. +// +// GitLab API docs: +// https://docs.gitlab.com/ce/api/users.html#delete-email-for-given-user +func (s *UsersService) DeleteEmailForUser(uid int, eid int, options ...OptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d/emails/%d", uid, eid) + + req, err := s.client.NewRequest("DELETE", u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index e180c00f2..1c0c7ca53 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -501,644 +501,644 @@ "revisionTime": "2017-01-23T00:46:44Z" }, { - "checksumSHA1": "Km15hcxupg+Fejy1CmPMv1b1Qew=", + "checksumSHA1": "G3L0lqSYuYeQGVeQ+QpfKvf64Bw=", "path": "github.com/aws/aws-sdk-go", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "jhBCqnseVTWZiSOXrAXWjSmuIOM=", + "checksumSHA1": "68ggvigBSHFisqSysgCZrp493Is=", "path": "github.com/aws/aws-sdk-go/aws", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "yyYr41HZ1Aq0hWc3J5ijXwYEcac=", "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "iA8gPEZQ0g2lMwf8gfjOVqUiYc4=", + "checksumSHA1": "lSxSARUjHuYCz1/axwEuQ7IiGxk=", "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "0Gfk83qXYimO87ZoK1lL9+ifWHo=", + "checksumSHA1": "uPsFA3K/51L3fy0FgMCoSGsiAoc=", "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "WKv1OkJtlhIHUjes6bB3QoWOA7o=", "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "6cj/zsRmcxkE1TLS+v910GbQYg0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "k4IMA27NIDHgZgvBxrKyJy16Y20=", "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "/EXbk/z2TWjWc1Hvb4QYs3Wmhb8=", "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "+yCOae0vRONrO27QiITkGWblOKk=", + "checksumSHA1": "WQ9XoTQbcKnmtubEjZY5DmHV2RE=", "path": "github.com/aws/aws-sdk-go/aws/endpoints", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "uqNleRWfPXWHwX7ROArYyOuIp0w=", + "checksumSHA1": "ThH5/ZhFCYrRxdRuot3FHUhyH9Y=", "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "24VtK/Hym9lC8LkZlGLMdFGq+5o=", "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "SvIsunO8D9MEKbetMENA4WRnyeE=", "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "wk7EyvDaHwb5qqoOP/4d3cV0708=", "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "O6hcK24yI6w7FA+g4Pbr+eQ7pys=", "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "Drt1JfLMa0DQEZLWrnMlTWaIcC8=", "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "VCTh+dEaqqhog5ncy/WTt9+/gFM=", "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "Rpu8KBtHZgvhkwHxUfaky+qW+G4=", "path": "github.com/aws/aws-sdk-go/private/protocol/restjson", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "lZ1z4xAbT8euCzKoAsnEYic60VE=", + "checksumSHA1": "gVjv1Z16iQ5ZB/LSkB58ppRqP+8=", "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "F6mth+G7dXN1GI+nktaGo8Lx8aE=", "path": "github.com/aws/aws-sdk-go/private/signer/v2", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "ZmojxECvjM6BeI752BPyZAmOhlo=", "path": "github.com/aws/aws-sdk-go/service/acm", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "PZpt6OZ+8tE7sPXLSVFZpyKbNOA=", + "checksumSHA1": "8aJdOLtEQYPwZFNF003s8BkZvKI=", "path": "github.com/aws/aws-sdk-go/service/apigateway", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "3ykAVetHFs9T3YivIPvRyiNFdys=", "path": "github.com/aws/aws-sdk-go/service/applicationautoscaling", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "/d8U22aF2+qYhWYscPzClHTDCP4=", "path": "github.com/aws/aws-sdk-go/service/autoscaling", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "n6v4S6jPpkHsS59Oj1EZPQIdRNg=", "path": "github.com/aws/aws-sdk-go/service/cloudformation", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "QLEaEFA3V4n+ohwENEoWV+AXBj4=", "path": "github.com/aws/aws-sdk-go/service/cloudfront", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "Vh3PtQEwIUabpoE7PsCZItUZuVc=", "path": "github.com/aws/aws-sdk-go/service/cloudtrail", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "aGx2atOHEXSowjXUQ3UoJ/t2LSI=", "path": "github.com/aws/aws-sdk-go/service/cloudwatch", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "Ez3+aU0QGRe4isLDFQuHNRyF3zA=", "path": "github.com/aws/aws-sdk-go/service/cloudwatchevents", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "+AjVMO3KUY7Wkh0vHRnJqRG8kGc=", "path": "github.com/aws/aws-sdk-go/service/cloudwatchlogs", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "uTt6pA8eB+udA7tC8ElLbr2eeK4=", "path": "github.com/aws/aws-sdk-go/service/codebuild", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "sqppuUIMPMBOnTRVR4BhHAoaTrY=", "path": "github.com/aws/aws-sdk-go/service/codecommit", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "u6cK2krOuDqi8gy5V316FvH34t0=", "path": "github.com/aws/aws-sdk-go/service/codedeploy", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "fK7MOfX/cV2DJ176+umySuuYh2s=", "path": "github.com/aws/aws-sdk-go/service/codepipeline", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "L8F5aJdwCvoNwrP6prtHSdklijM=", "path": "github.com/aws/aws-sdk-go/service/cognitoidentity", - "revision": "d643bdf04f2cc6f95424f9f4e69037a563fc0736", - "revisionTime": "2017-04-06T18:01:00Z", - "version": "=v1.8.10", - "versionExact": "v1.8.10" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "gSm1lj0J4klQMw7jHE0fU/RV+4Y=", "path": "github.com/aws/aws-sdk-go/service/configservice", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "SP6m/hn+Hj72wkgaAZ8NM/7s/18=", "path": "github.com/aws/aws-sdk-go/service/databasemigrationservice", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "2Su2xzCbUPbCdVkyWuXcmxAI2Rs=", "path": "github.com/aws/aws-sdk-go/service/directoryservice", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "Y4Wg7dxPIU3W1dqN3vnpSLA1ChQ=", "path": "github.com/aws/aws-sdk-go/service/dynamodb", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "2PIG7uhrvvDAjiNZINBVCgW/Uds=", + "checksumSHA1": "y/5vqS7mSsK4XJkOoPBz7VvMXo8=", "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "ClGPl4TLpf457zUeOEWyTvqBRjc=", "path": "github.com/aws/aws-sdk-go/service/ecr", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "c6KWQtc1bRCFs/IuIe/jgZXalBw=", "path": "github.com/aws/aws-sdk-go/service/ecs", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "4mBZS9FSCW73hcjj0CikPqpikag=", "path": "github.com/aws/aws-sdk-go/service/efs", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "P7GrpZV3eYQASV8Z+DeFuo9zbm4=", "path": "github.com/aws/aws-sdk-go/service/elasticache", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "DXs9Zpa2Db2adBjDi/EyFp6913E=", "path": "github.com/aws/aws-sdk-go/service/elasticbeanstalk", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "dv1QkeLjDyUlMQkbnLjm6l0mJHo=", "path": "github.com/aws/aws-sdk-go/service/elasticsearchservice", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "ir6xGAYAwIdWKgk7BVHNQWvlA/g=", "path": "github.com/aws/aws-sdk-go/service/elastictranscoder", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "sdFllfq+lllwyk0yMFmWzg+qs9Y=", "path": "github.com/aws/aws-sdk-go/service/elb", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "oJQzYnuAHAhKAtAuinSPEeDsXoU=", + "checksumSHA1": "ctX2iDPvGn6pEClNoSQuBG9SnHw=", "path": "github.com/aws/aws-sdk-go/service/elbv2", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "tLfj5mQiTOOhWdeU6hL5PYRAEP0=", "path": "github.com/aws/aws-sdk-go/service/emr", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "Yy7CkVZR1/vrcdMPWJmQMC2i5hk=", "path": "github.com/aws/aws-sdk-go/service/firehose", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "tuoOAm2gCN2txnIq1jKbCHqeQQM=", "path": "github.com/aws/aws-sdk-go/service/glacier", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "NoG5QpuGo3iLNk6DwwWsDCogfGY=", + "checksumSHA1": "qXkqj6yFLHLALSzgBrbvLIBPGDA=", "path": "github.com/aws/aws-sdk-go/service/iam", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "5ElupFtEcDvKa1yXTh6nR9HijMU=", "path": "github.com/aws/aws-sdk-go/service/inspector", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "Yzxk0tkTh2D9JP5I8gspLQLKu0U=", + "checksumSHA1": "mPiLIr/qcAhucTlT6KpWaXkkkbI=", "path": "github.com/aws/aws-sdk-go/service/kinesis", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "zeEh/FDxM81fU3X2ftWU2Z++iQg=", + "checksumSHA1": "cKNVED9npmrzs+4+i39c2bey3b8=", "path": "github.com/aws/aws-sdk-go/service/kms", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "H25POIGzyemmnJ+06HoAziXxW4I=", + "checksumSHA1": "plYDyL47QBcXLkztouyTzfRBfgw=", "path": "github.com/aws/aws-sdk-go/service/lambda", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "GFXjkh1wWzohbefi1k0N+zbkmU4=", "path": "github.com/aws/aws-sdk-go/service/lightsail", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "SqXsYVwBsvHwXRd2VAb5Us9F6Vw=", "path": "github.com/aws/aws-sdk-go/service/opsworks", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "5Br7nJBgOm6y67Z95CGZtOaxlFY=", "path": "github.com/aws/aws-sdk-go/service/rds", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "TIYqqHM4J5j5tWZR+FLpRpQzz7A=", "path": "github.com/aws/aws-sdk-go/service/redshift", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "e/lUvi2TAO9hms6HOzpX61exefw=", + "checksumSHA1": "u6KIk/dDTwHRqz2x8EFiaa4gUfY=", "path": "github.com/aws/aws-sdk-go/service/route53", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { - "checksumSHA1": "o7qpn0kxj43Ej/RwfCb9JbzfbfQ=", + "checksumSHA1": "gYdNJoRTGvblAO/A88lYgiYFmsI=", "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "/2UKYWNc/LRv+M/LQRpJqukcXzc=", "path": "github.com/aws/aws-sdk-go/service/ses", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "eUrUJOZg3sQHWyYKPRPO9OeN+a4=", "path": "github.com/aws/aws-sdk-go/service/sfn", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "CVWvzoJ3YBvEI8TdQWlqUxOt9lk=", "path": "github.com/aws/aws-sdk-go/service/simpledb", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "bJ8g3OhBAkxM+QaFrQCD0L0eWY8=", "path": "github.com/aws/aws-sdk-go/service/sns", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "jzKBnso2Psx3CyS+0VR1BzvuccU=", "path": "github.com/aws/aws-sdk-go/service/sqs", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "GPD+dDmDtseJFG8lB8aU58aszDg=", "path": "github.com/aws/aws-sdk-go/service/ssm", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "SdsHiTUR9eRarThv/i7y6/rVyF4=", "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "w3+CyiPRk1WUFFmueIRZkgQuHH0=", "path": "github.com/aws/aws-sdk-go/service/waf", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "QgNbH3Mxe4jiu3IN+vPAnz/IWbw=", "path": "github.com/aws/aws-sdk-go/service/wafregional", - "revision": "4bbd6fa3fdede4c68e941248f974b8951c17de89", - "revisionTime": "2017-04-18T18:52:59Z", - "version": "v1.8.13", - "versionExact": "v1.8.13" + "revision": "f6ea558f30e0a983d529b32c741e4caed17c7df0", + "revisionTime": "2017-04-21T18:17:16Z", + "version": "v1.8.16", + "versionExact": "v1.8.16" }, { "checksumSHA1": "nqw2Qn5xUklssHTubS5HDvEL9L4=", @@ -3075,6 +3075,12 @@ "revision": "deca6e17c056012b540aa2d2eae3ea1e63203b85", "revisionTime": "2016-10-26T18:16:49Z" }, + { + "checksumSHA1": "1mR4/KWIQEL8rzyDlCR4CRrTqGQ=", + "path": "github.com/xanzy/go-gitlab", + "revision": "5b756e2fdc9f21fd4791fa1453b8fe01af0f82e2", + "revisionTime": "2017-03-22T12:21:15Z" + }, { "checksumSHA1": "iHiMTBffQvWYlOLu3130JXuQpgQ=", "path": "github.com/xanzy/ssh-agent", diff --git a/website/config.rb b/website/config.rb index ed989b37d..52ebbd14b 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.terraform.io/" activate :hashicorp do |h| h.name = "terraform" - h.version = "0.9.3" + h.version = "0.9.4" h.github_slug = "hashicorp/terraform" end diff --git a/website/source/docs/commands/init.html.markdown b/website/source/docs/commands/init.html.markdown index 57aeaed89..495763f2c 100644 --- a/website/source/docs/commands/init.html.markdown +++ b/website/source/docs/commands/init.html.markdown @@ -21,7 +21,7 @@ initial files, loading any remote state, downloading modules, etc. This is the first command that should be run for any new or existing Terraform configuration per machine. This sets up all the local data -necessary to run Terraform that is typically not comitted to version +necessary to run Terraform that is typically not committed to version control. This command is always safe to run multiple times. Though subsequent runs diff --git a/website/source/docs/enterprise/vcs/bitbucket.html.md b/website/source/docs/enterprise/vcs/bitbucket.html.md index 1d02a69b5..d1a5633aa 100644 --- a/website/source/docs/enterprise/vcs/bitbucket.html.md +++ b/website/source/docs/enterprise/vcs/bitbucket.html.md @@ -53,7 +53,7 @@ You are now ready to use your personal token to manage builds and configurations ## Connecting Configurations Once you have linked a Bitbucket installation to your account or organization, -you are ready to begin creating Packer Builds and Terraform Enviroments linked +you are ready to begin creating Packer Builds and Terraform Environments linked to your desired Bitbucket Cloud repository. Terraform Enterprise environments are linked to individual GitHub repositories. diff --git a/website/source/docs/enterprise/vcs/gitlab.html.md b/website/source/docs/enterprise/vcs/gitlab.html.md index 44409a9dd..deaa80892 100644 --- a/website/source/docs/enterprise/vcs/gitlab.html.md +++ b/website/source/docs/enterprise/vcs/gitlab.html.md @@ -50,7 +50,7 @@ Navigate to https://atlas.hashicorp.com/settings/connections and click on “Con ## Connecting Configurations Once you have linked a GitLab installation to your account or organization, -you are ready to begin creating Packer Builds and Terraform Enviroments linked +you are ready to begin creating Packer Builds and Terraform Environments linked to your desired GitLab repository. Terraform Enterprise environments are linked to individual GitLab repositories. diff --git a/website/source/docs/import/importability.html.md b/website/source/docs/import/importability.html.md index 8fbdb4878..b6b22e609 100644 --- a/website/source/docs/import/importability.html.md +++ b/website/source/docs/import/importability.html.md @@ -174,6 +174,30 @@ To make a resource importable, please see the * openstack_networking_secgroup_v2 * openstack_networking_subnet_v2 +### OPC (Oracle Public Cloud) + +* opc_compute_acl +* opc_compute_image_list +* opc_compute_instance +* opc_compute_ip_address_association +* opc_compute_ip_address_prefix_set +* opc_compute_ip_address_reservation +* opc_compute_ip_association +* opc_compute_ip_network_exchange +* opc_compute_ip_network +* opc_compute_ip_reservation +* opc_compute_route +* opc_compute_sec_rule +* opc_compute_security_application +* opc_compute_security_association +* opc_compute_security_ip_list +* opc_compute_security_list +* opc_compute_security_protocol +* opc_compute_security_rule +* opc_compute_ssh_key +* opc_compute_storage_volume_snapshot +* opc_compute_storage_volume + ### PostgreSQL * postgresql_database diff --git a/website/source/docs/providers/aws/d/ami_ids.html.markdown b/website/source/docs/providers/aws/d/ami_ids.html.markdown index 526977bdc..8bad15bee 100644 --- a/website/source/docs/providers/aws/d/ami_ids.html.markdown +++ b/website/source/docs/providers/aws/d/ami_ids.html.markdown @@ -46,6 +46,7 @@ options to narrow down the list AWS returns. ## Attributes Reference -`ids` is set to the list of AMI IDs. +`ids` is set to the list of AMI IDs, sorted by creation time in descending +order. [1]: http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html diff --git a/website/source/docs/providers/aws/d/ebs_snapshot_ids.html.markdown b/website/source/docs/providers/aws/d/ebs_snapshot_ids.html.markdown index 6d4ef617d..dfe472b5f 100644 --- a/website/source/docs/providers/aws/d/ebs_snapshot_ids.html.markdown +++ b/website/source/docs/providers/aws/d/ebs_snapshot_ids.html.markdown @@ -43,6 +43,7 @@ several valid keys, for a full reference, check out ## Attributes Reference -`ids` is set to the list of EBS snapshot IDs. +`ids` is set to the list of EBS snapshot IDs, sorted by creation time in +descending order. [1]: http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-snapshots.html diff --git a/website/source/docs/providers/aws/d/subnet_ids.html.markdown b/website/source/docs/providers/aws/d/subnet_ids.html.markdown index 7cf34ffa6..871da0ca2 100644 --- a/website/source/docs/providers/aws/d/subnet_ids.html.markdown +++ b/website/source/docs/providers/aws/d/subnet_ids.html.markdown @@ -31,10 +31,33 @@ output "subnet_cidr_blocks" { } ``` +The following example retrieves a list of all subnets in a VPC with a custom +tag of `Tier` set to a value of "Private" so that the `aws_instance` resource +can loop through the subnets, putting instances across availability zones. + +```hcl +data "aws_subnet_ids" "private" { + vpc_id = "${var.vpc_id}" + tags { + Tier = "Private" + } +} + +resource "aws_instance" "app" { + count = "3" + ami = "${var.ami}" + instance_type = "t2.micro" + subnet_id = "${element(data.aws_subnet_ids.private.ids, count.index)}" +} +``` + ## Argument Reference * `vpc_id` - (Required) The VPC ID that you want to filter from. +* `tags` - (Optional) A mapping of tags, each pair of which must exactly match + a pair on the desired subnets. + ## Attributes Reference * `ids` - Is a list of all the subnet ids found. If none found. This data source will fail out. diff --git a/website/source/docs/providers/aws/r/alb_listener_rule.html.markdown b/website/source/docs/providers/aws/r/alb_listener_rule.html.markdown index 50de244d0..6bfe263c7 100644 --- a/website/source/docs/providers/aws/r/alb_listener_rule.html.markdown +++ b/website/source/docs/providers/aws/r/alb_listener_rule.html.markdown @@ -63,12 +63,12 @@ The following arguments are supported: * `action` - (Required) An Action block. Action blocks are documented below. * `condition` - (Required) A Condition block. Condition blocks are documented below. -Action Blocks (for `default_action`) support the following: +Action Blocks (for `action`) support the following: * `target_group_arn` - (Required) The ARN of the Target Group to which to route traffic. * `type` - (Required) The type of routing action. The only valid value is `forward`. -Condition Blocks (for `default_condition`) support the following: +Condition Blocks (for `condition`) support the following: * `field` - (Required) The name of the field. Must be one of `path-pattern` for path based routing or `host-header` for host based routing. * `values` - (Required) The path patterns to match. A maximum of 1 can be defined. diff --git a/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown b/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown index ee8b70c1f..e55701523 100644 --- a/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown +++ b/website/source/docs/providers/aws/r/api_gateway_usage_plan.html.markdown @@ -72,8 +72,8 @@ The API Gateway Usage Plan argument layout is a structure composed of several su #### Api Stages arguments - * `api_id` (Optional) - API Id of the associated API stage in a usage plan. - * `stage` (Optional) - API stage name of the associated API stage in a usage plan. + * `api_id` (Required) - API Id of the associated API stage in a usage plan. + * `stage` (Required) - API stage name of the associated API stage in a usage plan. #### Quota Settings Arguments diff --git a/website/source/docs/providers/aws/r/cloudformation_stack.html.markdown b/website/source/docs/providers/aws/r/cloudformation_stack.html.markdown index 6948fa97a..8a1a8bbf2 100644 --- a/website/source/docs/providers/aws/r/cloudformation_stack.html.markdown +++ b/website/source/docs/providers/aws/r/cloudformation_stack.html.markdown @@ -73,4 +73,4 @@ The following arguments are supported: The following attributes are exported: * `id` - A unique identifier of the stack. -* `outputs` - A list of output structures. +* `outputs` - A map of outputs from the stack. diff --git a/website/source/docs/providers/aws/r/cloudfront_distribution.html.markdown b/website/source/docs/providers/aws/r/cloudfront_distribution.html.markdown index 8f7b7db8e..e28b781de 100644 --- a/website/source/docs/providers/aws/r/cloudfront_distribution.html.markdown +++ b/website/source/docs/providers/aws/r/cloudfront_distribution.html.markdown @@ -316,6 +316,10 @@ argument is not required. CloudFront to use when communicating with your origin over HTTPS. A list of one or more of `SSLv3`, `TLSv1`, `TLSv1.1`, and `TLSv1.2`. + * `origin_keepalive_timeout` - (Optional) The Custom KeepAlive timeout, in seconds. Value must be between `1` and `60`. + + * `origin_read_timeout` - (Optional) The Custom Read timeout, in seconds. Value must be between `4` and `60`. + ##### S3 Origin Config Arguments * `origin_access_identity` (Optional) - The [CloudFront origin access diff --git a/website/source/docs/providers/aws/r/cloudwatch_event_target.html.markdown b/website/source/docs/providers/aws/r/cloudwatch_event_target.html.markdown index 161097863..252beb4c6 100644 --- a/website/source/docs/providers/aws/r/cloudwatch_event_target.html.markdown +++ b/website/source/docs/providers/aws/r/cloudwatch_event_target.html.markdown @@ -47,11 +47,12 @@ resource "aws_kinesis_stream" "test_stream" { ## Argument Reference -> **Note:** `input` and `input_path` are mutually exclusive options. + -> **Note:** In order to be able to have your AWS Lambda function or SNS topic invoked by a CloudWatch Events rule, you must setup the right permissions using [`aws_lambda_permission`](https://www.terraform.io/docs/providers/aws/r/lambda_permission.html) or [`aws_sns_topic.policy`](https://www.terraform.io/docs/providers/aws/r/sns_topic.html#policy). - More info here [here](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/EventsResourceBasedPermissions.html). + More info [here](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/EventsResourceBasedPermissions.html). The following arguments are supported: diff --git a/website/source/docs/providers/aws/r/instance.html.markdown b/website/source/docs/providers/aws/r/instance.html.markdown index 4d8725de2..fea3c0cdb 100644 --- a/website/source/docs/providers/aws/r/instance.html.markdown +++ b/website/source/docs/providers/aws/r/instance.html.markdown @@ -80,12 +80,14 @@ instances. See [Shutdown Behavior](https://docs.aws.amazon.com/AWSEC2/latest/Use * `ipv6_address_count`- (Optional) A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet. * `ipv6_addresses` - (Optional) Specify one or more IPv6 addresses from the range of the subnet to associate with the primary network interface * `tags` - (Optional) A mapping of tags to assign to the resource. +* `volume_tags` - (Optional) A mapping of tags to assign to the devices created by the instance at launch time. * `root_block_device` - (Optional) Customize details about the root block device of the instance. See [Block Devices](#block-devices) below for details. * `ebs_block_device` - (Optional) Additional EBS block devices to attach to the instance. See [Block Devices](#block-devices) below for details. * `ephemeral_block_device` - (Optional) Customize Ephemeral (also known as "Instance Store") volumes on the instance. See [Block Devices](#block-devices) below for details. +* `network_interface` - (Optional) Customize network interfaces to be attached at instance boot time. See [Network Interfaces](#network-interfaces) below for more details. ## Block devices @@ -149,6 +151,59 @@ resources cannot be automatically detected by Terraform. After making updates to block device configuration, resource recreation can be manually triggered by using the [`taint` command](/docs/commands/taint.html). +## Network Interfaces + +Each of the `network_interface` blocks attach a network interface to an EC2 Instance during boot time. However, because +the network interface is attached at boot-time, replacing/modifying the network interface **WILL** trigger a recreation +of the EC2 Instance. If you should need at any point to detach/modify/re-attach a network interface to the instance, use +the `aws_network_interface` or `aws_network_interface_attachment` resources instead. + +The `network_interface` configuration block _does_, however, allow users to supply their own network interface to be used +as the default network interface on an EC2 Instance, attached at `eth0`. + +Each `network_interface` block supports the following: + +* `device_index` - (Required) The integer index of the network interface attachment. Limited by instance type. +* `network_interface_id` - (Required) The ID of the network interface to attach. +* `delete_on_termination` - (Optional) Whether or not to delete the network interface on instance termination. Defaults to `false`. + +### Example + +```hcl +resource "aws_vpc" "my_vpc" { + cidr_block = "172.16.0.0/16" + tags { + Name = "tf-example" + } +} + +resource "aws_subnet" "my_subnet" { + vpc_id = "${aws_vpc.my_vpc.id}" + cidr_block = "172.16.10.0/24" + availability_zone = "us-west-2a" + tags { + Name = "tf-example" + } +} + +resource "aws_network_interface" "foo" { + subnet_id = "${aws_subnet.my_subnet.id}" + private_ips = ["172.16.10.100"] + tags { + Name = "primary_network_interface" + } +} + +resource "aws_instance" "foo" { + ami = "ami-22b9a343" // us-west-2 + instance_type = "t2.micro" + network_interface { + network_interface_id = "${aws_network_interface.foo.id}" + device_index = 0 + } +} +``` + ## Attributes Reference The following attributes are exported: @@ -161,6 +216,7 @@ The following attributes are exported: is only available if you've enabled DNS hostnames for your VPC * `public_ip` - The public IP address assigned to the instance, if applicable. **NOTE**: If you are using an [`aws_eip`](/docs/providers/aws/r/eip.html) with your instance, you should refer to the EIP's address directly and not use `public_ip`, as this field will change after the EIP is attached. * `network_interface_id` - The ID of the network interface that was created with the instance. +* `primary_network_interface_id` - The ID of the instance's primary network interface. * `private_dns` - The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC diff --git a/website/source/docs/providers/dnsimple/r/record.html.markdown b/website/source/docs/providers/dnsimple/r/record.html.markdown index b91701b21..f4bb50053 100644 --- a/website/source/docs/providers/dnsimple/r/record.html.markdown +++ b/website/source/docs/providers/dnsimple/r/record.html.markdown @@ -58,3 +58,13 @@ The following attributes are exported: * `priority` - The priority of the record * `domain_id` - The domain ID of the record * `hostname` - The FQDN of the record + +## Import + +DNSimple resources can be imported using their domain name and numeric ID, e.g. + +``` +$ terraform import dnsimple_record.resource_name example.com_1234 +``` + +The numeric ID can be found in the URL when editing a record on the dnsimple web dashboard. diff --git a/website/source/docs/providers/gitlab/index.html.markdown b/website/source/docs/providers/gitlab/index.html.markdown new file mode 100644 index 000000000..ed0831f5b --- /dev/null +++ b/website/source/docs/providers/gitlab/index.html.markdown @@ -0,0 +1,41 @@ +--- +layout: "gitlab" +page_title: "Provider: GitLab" +sidebar_current: "docs-gitlab-index" +description: |- + The GitLab provider is used to interact with GitLab organization resources. +--- + +# GitLab Provider + +The GitLab provider is used to interact with GitLab organization resources. + +The provider allows you to manage your GitLab organization's members and teams easily. +It needs to be configured with the proper credentials before it can be used. + +Use the navigation to the left to read about the available resources. + +## Example Usage + +```hcl +# Configure the GitLab Provider +provider "gitlab" { + token = "${var.github_token}" +} + +# Add a project to the organization +resource "gitlab_project" "sample_project" { + ... +} +``` + +## Argument Reference + +The following arguments are supported in the `provider` block: + +* `token` - (Optional) This is the GitLab personal access token. It must be provided, but + it can also be sourced from the `GITLAB_TOKEN` environment variable. + +* `base_url` - (Optional) This is the target GitLab base API endpoint. Providing a value is a + requirement when working with GitLab CE or GitLab Enterprise. It is optional to provide this value and + it can also be sourced from the `GITLAB_BASE_URL` environment variable. The value must end with a slash. diff --git a/website/source/docs/providers/gitlab/r/project.html.markdown b/website/source/docs/providers/gitlab/r/project.html.markdown new file mode 100644 index 000000000..9a1eae738 --- /dev/null +++ b/website/source/docs/providers/gitlab/r/project.html.markdown @@ -0,0 +1,58 @@ +--- +layout: "gitlab" +page_title: "GitLab: gitlab_project" +sidebar_current: "docs-gitlab-resource-project" +description: |- + Creates and manages projects within Github organizations +--- + +# gitlab\_project + +This resource allows you to create and manage projects within your +GitLab organization. + + +## Example Usage + +```hcl +resource "gitlab_repository" "example" { + name = "example" + description = "My awesome codebase" + + visbility_level = "public" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the project. + +* `description` - (Optional) A description of the project. + +* `default_branch` - (Optional) The default branch for the project. + +* `issues_enabled` - (Optional) Enable issue tracking for the project. + +* `merge_requests_enabled` - (Optional) Enable merge requests for the project. + +* `wiki_enabled` - (Optional) Enable wiki for the project. + +* `snippets_enabled` - (Optional) Enable snippets for the project. + +* `visbility_level` - (Optional) Set to `public` to create a public project. + Valid values are `private`, `internal`, `public`. + Repositories are created as private by default. + +## Attributes Reference + +The following additional attributes are exported: + +* `ssh_url_to_repo` - URL that can be provided to `git clone` to clone the + repository via SSH. + +* `http_url_to_repo` - URL that can be provided to `git clone` to clone the + repository via HTTP. + +* `web_url` - URL that can be used to find the project in a browser. diff --git a/website/source/docs/providers/google/r/compute_forwarding_rule.html.markdown b/website/source/docs/providers/google/r/compute_forwarding_rule.html.markdown index 845a7450b..a8c735187 100644 --- a/website/source/docs/providers/google/r/compute_forwarding_rule.html.markdown +++ b/website/source/docs/providers/google/r/compute_forwarding_rule.html.markdown @@ -3,7 +3,7 @@ layout: "google" page_title: "Google: google_compute_forwarding_rule" sidebar_current: "docs-google-compute-forwarding-rule" description: |- - Manages a Target Pool within GCE. + Manages a Forwarding Rule within GCE. --- # google\_compute\_forwarding\_rule @@ -54,8 +54,9 @@ The following arguments are supported: * `port_range` - (Optional) A range e.g. "1024-2048" or a single port "1024" (defaults to all ports!). Only used for external load balancing. -* `ports` - (Optional) A list of ports to use for internal load balancing - (defaults to all ports). +* `ports` - (Optional) A list of ports (maximum of 5) to use for internal load + balancing. Packets addressed to these ports will be forwarded to the backends + configured with this forwarding rule. Required for internal load balancing. * `project` - (Optional) The project in which the resource belongs. If it is not provided, the provider project is used. diff --git a/website/source/docs/providers/heroku/r/app.html.markdown b/website/source/docs/providers/heroku/r/app.html.markdown index 410f01ead..0cf064e4f 100644 --- a/website/source/docs/providers/heroku/r/app.html.markdown +++ b/website/source/docs/providers/heroku/r/app.html.markdown @@ -22,6 +22,10 @@ resource "heroku_app" "default" { config_vars { FOOBAR = "baz" } + + buildpacks = [ + "heroku/go" + ] } ``` @@ -34,11 +38,14 @@ The following arguments are supported: * `region` - (Required) The region that the app should be deployed in. * `stack` - (Optional) The application stack is what platform to run the application in. +* `buildpacks` - (Optional) Buildpack names or URLs for the application. + Buildpacks configured externally won't be altered if this is not present. * `config_vars` - (Optional) Configuration variables for the application. The config variables in this map are not the final set of configuration variables, but rather variables you want present. That is, other configuration variables set externally won't be removed by Terraform if they aren't present in this list. +* `space` - (Optional) The name of a private space to create the app in. * `organization` - (Optional) A block that can be specified once to define organization settings for this app. The fields for this block are documented below. @@ -58,6 +65,7 @@ The following attributes are exported: unique ID. * `stack` - The application stack is what platform to run the application in. +* `space` - The private space the app should run in. * `region` - The region that the app should be deployed in. * `git_url` - The Git URL for the application. This is used for deploying new versions of the app. diff --git a/website/source/docs/providers/heroku/r/space.html.markdown b/website/source/docs/providers/heroku/r/space.html.markdown new file mode 100644 index 000000000..089fe2159 --- /dev/null +++ b/website/source/docs/providers/heroku/r/space.html.markdown @@ -0,0 +1,48 @@ +--- +layout: "heroku" +page_title: "Heroku: heroku_space" +sidebar_current: "docs-heroku-resource-space" +description: |- + Provides a Heroku Space resource for running apps in isolated, highly available, secure app execution environments. +--- + +# heroku\_space + +Provides a Heroku Space resource for running apps in isolated, highly available, secure app execution environments. + +## Example Usage + +```hcl +// Create a new Heroku space +resource "heroku_space" "default" { + name = "test-space" + organization = "my-company" + region = "virginia" +} + +// Create a new Heroku app in test-space +resource "heroku_app" "default" { + name = "test-app" + space = "${heroku_space.default.name}" + organization = { + name = "my-company" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the space. +* `organization` - (Required) The name of the organization which will own the space. +* `region` - (Optional) The region that the space should be created in. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the space. +* `name` - The space's name. +* `organization` - The space's organization. +* `region` - The space's region. diff --git a/website/source/docs/providers/oneandone/r/firewall_policy.html.markdown b/website/source/docs/providers/oneandone/r/firewall_policy.html.markdown index c5e2eb32f..8e86211e7 100644 --- a/website/source/docs/providers/oneandone/r/firewall_policy.html.markdown +++ b/website/source/docs/providers/oneandone/r/firewall_policy.html.markdown @@ -46,13 +46,13 @@ resource "oneandone_firewall_policy" "fw" { The following arguments are supported: -* `description` - (Optional) [string] Description for the VPN -* `name` - (Required) [string] The name of the VPN. +* `description` - (Optional) Description for the VPN +* `name` - (Required) The name of the VPN. Firewall Policy Rules (`rules`) support the follwing: -* `protocol` - (Required) [String] The protocol for the rule ["TCP", "UDP", "TCP/UDP", "ICMP", "IPSEC"] -* `port_from` - (Optional) [String] Defines the start range of the allowed port -* `port_to` - (Optional) [String] Defines the end range of the allowed port -* `source_ip` - (Optional) [String] Only traffic directed to the respective IP address +* `protocol` - (Required) The protocol for the rule. Allowed values are `TCP`, `UDP`, `TCP/UDP`, `ICMP` and `IPSEC`. +* `port_from` - (Optional) Defines the start range of the allowed port +* `port_to` - (Optional) Defines the end range of the allowed port +* `source_ip` - (Optional) Only traffic directed to the respective IP address diff --git a/website/source/docs/providers/oneandone/r/loadbalancer.html.markdown b/website/source/docs/providers/oneandone/r/loadbalancer.html.markdown index 35dc4e7e2..6c30344fd 100644 --- a/website/source/docs/providers/oneandone/r/loadbalancer.html.markdown +++ b/website/source/docs/providers/oneandone/r/loadbalancer.html.markdown @@ -42,20 +42,20 @@ resource "oneandone_loadbalancer" "lb" { The following arguments are supported: -* `name` - (Required) [String] The name of the load balancer. -* `description` - (Optional) [String] Description for the load balancer -* `method` - (Required) [String] Balancing procedure ["ROUND_ROBIN", "LEAST_CONNECTIONS"] -* `datacenter` - (Optional) [String] Location of desired 1and1 datacenter ["DE", "GB", "US", "ES" ] -* `persistence` - (Optional) [Boolean] True/false defines whether persistence should be turned on/off -* `persistence_time` - (Optional) [Integer] Persistance duration in seconds -* `health_check_test` - (Optional) [String] ["TCP", "ICMP"] -* `health_check_test_interval` - (Optional) [String] -* `health_check_test_path` - (Optional) [String] -* `health_check_test_parser` - (Optional) [String] +* `name` - (Required) The name of the load balancer. +* `description` - (Optional) Description for the load balancer +* `method` - (Required) Balancing procedure Can be `ROUND_ROBIN` or `LEAST_CONNECTIONS` +* `datacenter` - (Optional) Location of desired 1and1 datacenter. Can be `DE`, `GB`, `US` or `ES` +* `persistence` - (Optional) True/false defines whether persistence should be turned on/off +* `persistence_time` - (Optional) Persistence duration in seconds +* `health_check_test` - (Optional) Can be `TCP` or`ICMP`. +* `health_check_test_interval` - (Optional) +* `health_check_test_path` - (Optional) +* `health_check_test_parser` - (Optional) Loadbalancer rules (`rules`) support the following -* `protocol` - (Required) [String] The protocol for the rule ["TCP", "UDP", "TCP/UDP", "ICMP", "IPSEC"] -* `port_balancer` - (Required) [String] -* `port_server` - (Required) [String] -* `source_ip` - (Required) [String] +* `protocol` - (Required) The protocol for the rule. Allowed values are `TCP`, `UDP`, `TCP/UDP`, `ICMP` and `IPSEC`. +* `port_balancer` - (Required) +* `port_server` - (Required) +* `source_ip` - (Required) diff --git a/website/source/docs/providers/oneandone/r/monitoring_policy.html.markdown b/website/source/docs/providers/oneandone/r/monitoring_policy.html.markdown index 71e0f5120..bc93f9d66 100644 --- a/website/source/docs/providers/oneandone/r/monitoring_policy.html.markdown +++ b/website/source/docs/providers/oneandone/r/monitoring_policy.html.markdown @@ -120,58 +120,58 @@ resource "oneandone_monitoring_policy" "mp" { The following arguments are supported: -* `name` - (Required) [string] The name of the VPN. -* `description` - (Optional) [string] Description for the VPN -* `email` - (Optional) [String] Email address to which notifications monitoring system will send -* `agent- (Required)[Boolean] Indicates which monitoring type will be used. True: To use this monitoring type, you must install an agent on the server. False: Monitor a server without installing an agent. Note: If you do not install an agent, you cannot retrieve information such as free hard disk space or ongoing processes. +* `name` - (Required) The name of the VPN. +* `description` - (Optional) Description for the VPN +* `email` - (Optional) Email address to which notifications monitoring system will send +* `agent- (Required) Indicates which monitoring type will be used. True: To use this monitoring type, you must install an agent on the server. False: Monitor a server without installing an agent. Note: If you do not install an agent, you cannot retrieve information such as free hard disk space or ongoing processes. Monitoring Policy Thresholds (`thresholds`) support the following: -* `cpu - (Required)[Type] CPU thresholds - * `warning - (Required)[Type] Warning alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. - * `critical - (Required)[Type] Critical alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. -* `ram - (Required)[Type] RAM threshold - * `warning - (Required)[Type] Warning alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. - * `critical - (Required)[Type] Critical alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. -* `disk - (Required)[Type] Hard Disk threshold - * `warning - (Required)[Type] Warning alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. - * `critical - (Required)[Type] Critical alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. -* `transfer - (Required)[Type] Data transfer threshold - * `warning - (Required)[Type] Warning alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. - * `critical - (Required)[Type] Critical alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. -* `internal_ping - (Required)[type] Ping threshold - * `warning - (Required)[Type] Warning alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. - * `critical - (Required)[Type] Critical alert - * `value - (Required)[Integer] Warning to be issued when the threshold is reached. from 1 to 100 - * `alert - (Required)[Boolean] If set true warning will be issued. +* `cpu - (Required) CPU thresholds + * `warning - (Required)Warning alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. + * `critical - (Required) Critical alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. +* `ram - (Required) RAM threshold + * `warning - (Required) Warning alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. + * `critical - (Required) Critical alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. +* `disk - (Required) Hard Disk threshold + * `warning - (Required) Warning alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. + * `critical - (Required) Critical alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. +* `transfer - (Required) Data transfer threshold + * `warning - (Required) Warning alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. + * `critical - (Required) Critical alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. +* `internal_ping - (Required) Ping threshold + * `warning - (Required) Warning alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. + * `critical - (Required) Critical alert + * `value - (Required) Warning to be issued when the threshold is reached. from 1 to 100 + * `alert - (Required) If set true warning will be issued. Monitoring Policy Ports (`ports`) support the following: -* `email_notification - (Required)[boolean] If set true email will be sent. -* `port - (Required)[Integer] Port number. -* `protocol - (Required)[String] The protocol of the port ["TCP", "UDP", "TCP/UDP", "ICMP", "IPSEC"] -* `alert_if - (Required)[String] Condition for the alert to be issued. +* `email_notification - (Required) If set true email will be sent. +* `port - (Required) Port number. +* `protocol` - (Required) The protocol of the port. Allowed values are `TCP`, `UDP`, `TCP/UDP`, `ICMP` and `IPSEC`. +* `alert_if - (Required) Condition for the alert to be issued. Monitoring Policy Ports (`processes`) support the following: -* `email_notification - (Required)[Boolean] If set true email will be sent. -* `process - (Required)[Integer] Process name. -* `alert_if - (Required)[String] Condition for the alert to be issued. +* `email_notification - (Required) If set true email will be sent. +* `process - (Required) Process name. +* `alert_if - (Required) Condition for the alert to be issued. diff --git a/website/source/docs/providers/oneandone/r/private_network.html.markdown b/website/source/docs/providers/oneandone/r/private_network.html.markdown index 1ea270356..31061c1e4 100644 --- a/website/source/docs/providers/oneandone/r/private_network.html.markdown +++ b/website/source/docs/providers/oneandone/r/private_network.html.markdown @@ -30,9 +30,9 @@ resource "oneandone_private_network" "pn" { The following arguments are supported: -* `datacenter` - (Optional)[string] Location of desired 1and1 datacenter ["DE", "GB", "US", "ES" ] -* `description` - (Optional)[string] Description for the shared storage -* `name` - (Required)[string] The name of the private network -* `network_address` - (Optional)[string] Network address for the private network -* `subnet_mask` - (Optional)[string] Subnet mask for the private network -* `server_ids` (Optional)[Collection] List of servers that are to be associated with the private network +* `datacenter` - (Optional) Location of desired 1and1 datacenter. Can be `DE`, `GB`, `US` or `ES`. +* `description` - (Optional) Description for the shared storage +* `name` - (Required) The name of the private network +* `network_address` - (Optional) Network address for the private network +* `subnet_mask` - (Optional) Subnet mask for the private network +* `server_ids` (Optional) List of servers that are to be associated with the private network diff --git a/website/source/docs/providers/oneandone/r/public_ip.html.markdown b/website/source/docs/providers/oneandone/r/public_ip.html.markdown index 7fd01cd74..fbb49d1de 100644 --- a/website/source/docs/providers/oneandone/r/public_ip.html.markdown +++ b/website/source/docs/providers/oneandone/r/public_ip.html.markdown @@ -24,6 +24,6 @@ resource "oneandone_vpn" "vpn" { The following arguments are supported: -* `datacenter` - (Optional)[string] Location of desired 1and1 datacenter ["DE", "GB", "US", "ES" ] -* `description` - (Optional)[string] Description of the VPN -* `name` -(Required)[string] The name of the VPN. +* `datacenter` - (Optional) Location of desired 1and1 datacenter. Can be `DE`, `GB`, `US` or `ES` +* `description` - (Optional) Description of the VPN +* `name` -(Required) The name of the VPN. diff --git a/website/source/docs/providers/oneandone/r/server.html.markdown b/website/source/docs/providers/oneandone/r/server.html.markdown index 5a5f88b73..55062c141 100644 --- a/website/source/docs/providers/oneandone/r/server.html.markdown +++ b/website/source/docs/providers/oneandone/r/server.html.markdown @@ -42,19 +42,19 @@ resource "oneandone_server" "server" { The following arguments are supported: -* `cores_per_processor` -(Required)[integer] Number of cores per processor -* `datacenter` - (Optional)[string] Location of desired 1and1 datacenter ["DE", "GB", "US", "ES" ] -* `description` - (Optional)[string] Description of the server -* `firewall_policy_id` - (Optional)[string] ID of firewall policy -* `hdds` - (Required)[collection] List of HDDs. One HDD must be main. -* `*disk_size` -(Required)[integer] The size of HDD -* `*is_main` - (Optional)[boolean] Indicates if HDD is to be used as main hard disk of the server -* `image` -(Required)[string] The name of a desired image to be provisioned with the server -* `ip` - (Optional)[string] IP address for the server -* `loadbalancer_id` - (Optional)[string] ID of the load balancer -* `monitoring_policy_id` - (Optional)[string] ID of monitoring policy -* `name` -(Required)[string] The name of the server. -* `password` - (Optional)[string] Desired password. -* `ram` -(Required)[float] Size of ram. -* `ssh_key_path` - (Optional)[string] Path to private ssh key -* `vcores` -(Required)[integer] Number of virtual cores. +* `cores_per_processor` -(Required) Number of cores per processor +* `datacenter` - (Optional) Location of desired 1and1 datacenter. Can be `DE`, `GB`, `US` or `ES` +* `description` - (Optional) Description of the server +* `firewall_policy_id` - (Optional) ID of firewall policy +* `hdds` - (Required) List of HDDs. One HDD must be main. +* `*disk_size` -(Required) The size of HDD +* `*is_main` - (Optional) Indicates if HDD is to be used as main hard disk of the server +* `image` -(Required) The name of a desired image to be provisioned with the server +* `ip` - (Optional) IP address for the server +* `loadbalancer_id` - (Optional) ID of the load balancer +* `monitoring_policy_id` - (Optional) ID of monitoring policy +* `name` -(Required) The name of the server. +* `password` - (Optional) Desired password. +* `ram` -(Required) Size of ram. +* `ssh_key_path` - (Optional) Path to private ssh key +* `vcores` -(Required) Number of virtual cores. diff --git a/website/source/docs/providers/oneandone/r/shared_storage.html.markdown b/website/source/docs/providers/oneandone/r/shared_storage.html.markdown index 0c7730b9b..78343ffe4 100644 --- a/website/source/docs/providers/oneandone/r/shared_storage.html.markdown +++ b/website/source/docs/providers/oneandone/r/shared_storage.html.markdown @@ -35,9 +35,9 @@ resource "oneandone_shared_storage" "storage" { The following arguments are supported: -* `datacenter` - (Optional)[string] Location of desired 1and1 datacenter ["DE", "GB", "US", "ES" ] -* `description` - (Optional)[string] Description for the shared storage -* `size` - (Required)[string] Size of the shared storage -* `storage_servers` (Optional)[Collection] List of servers that will have access to the stored storage - * `id` - (Required) [string] ID of the server - * `rights` - (Required)[string] Access rights to be assigned to the server ["RW","R"] +* `datacenter` - (Optional) Location of desired 1and1 datacenter. Can be `DE`, `GB`, `US` or `ES` +* `description` - (Optional) Description for the shared storage +* `size` - (Required) Size of the shared storage +* `storage_servers` (Optional) List of servers that will have access to the stored storage + * `id` - (Required) ID of the server + * `rights` - (Required) Access rights to be assigned to the server. Can be `RW` or `R` diff --git a/website/source/docs/providers/oneandone/r/vpn.html.markdown b/website/source/docs/providers/oneandone/r/vpn.html.markdown index 7f9aecf78..81de79ed1 100644 --- a/website/source/docs/providers/oneandone/r/vpn.html.markdown +++ b/website/source/docs/providers/oneandone/r/vpn.html.markdown @@ -24,7 +24,7 @@ resource "oneandone_public_ip" "ip" { The following arguments are supported: -* `datacenter` - (Optional)[string] Location of desired 1and1 datacenter ["DE", "GB", "US", "ES" ] -* `ip_type` - (Required)[string] IPV4 or IPV6 -* `reverese_dns` - [Optional](string) +* `datacenter` - (Optional) Location of desired 1and1 datacenter. Can be `DE`, `GB`, `US` or `ES`. +* `ip_type` - (Required) IPV4 or IPV6 +* `reverese_dns` - (Optional) diff --git a/website/source/docs/providers/opc/d/opc_compute_network_interface.html.markdown b/website/source/docs/providers/opc/d/opc_compute_network_interface.html.markdown index ab924e5d4..8ab2d31cb 100644 --- a/website/source/docs/providers/opc/d/opc_compute_network_interface.html.markdown +++ b/website/source/docs/providers/opc/d/opc_compute_network_interface.html.markdown @@ -12,7 +12,7 @@ Use this data source to access the configuration of an instance's network interf ## Example Usage -``` +```hcl data "opc_compute_network_interface" "foo" { instance_id = "${opc_compute_instance.my_instance.id}" instance_name = "${opc_compute_instance.my_instance.name}" diff --git a/website/source/docs/providers/opc/d/opc_compute_vnic.html.markdown b/website/source/docs/providers/opc/d/opc_compute_vnic.html.markdown index 8656c85c2..bef1b5c66 100644 --- a/website/source/docs/providers/opc/d/opc_compute_vnic.html.markdown +++ b/website/source/docs/providers/opc/d/opc_compute_vnic.html.markdown @@ -12,7 +12,7 @@ Use this data source to access the configuration of a Virtual NIC. ## Example Usage -``` +```hcl data "opc_compute_vnic" "current" { name = "my_vnic_name" } diff --git a/website/source/docs/providers/opc/index.html.markdown b/website/source/docs/providers/opc/index.html.markdown index b23d54687..13c626ead 100644 --- a/website/source/docs/providers/opc/index.html.markdown +++ b/website/source/docs/providers/opc/index.html.markdown @@ -14,7 +14,7 @@ Use the navigation to the left to read about the available resources. ## Example Usage -``` +```hcl # Configure the Oracle Public Cloud provider "opc" { user = "..." diff --git a/website/source/docs/providers/opc/r/opc_compute_acl.html.markdown b/website/source/docs/providers/opc/r/opc_compute_acl.html.markdown index b69aab166..ffc37a29d 100644 --- a/website/source/docs/providers/opc/r/opc_compute_acl.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_acl.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_acl`` resource creates and manages an ACL in an OPC identity d ## Example Usage -``` +```hcl resource "opc_compute_acl" "default" { name = "ACL1" description = "This is a description for an acl" @@ -40,6 +40,6 @@ In addition to the above, the following values are exported: ACL's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_acl.acl1 example +```shell +$ terraform import opc_compute_acl.acl1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_image_list.html.markdown b/website/source/docs/providers/opc/r/opc_compute_image_list.html.markdown index 727114c2e..1e10ec352 100644 --- a/website/source/docs/providers/opc/r/opc_compute_image_list.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_image_list.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_image_list`` resource creates and manages an Image List in an ## Example Usage -``` +```hcl resource "opc_compute_image_list" "test" { name = "imagelist1" description = "This is a description of the Image List" @@ -34,6 +34,6 @@ The following arguments are supported: Image List's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_image_list.imagelist1 example +```shell +$ terraform import opc_compute_image_list.imagelist1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_image_list_entry.html.markdown b/website/source/docs/providers/opc/r/opc_compute_image_list_entry.html.markdown index b062773e8..293bb6c4b 100644 --- a/website/source/docs/providers/opc/r/opc_compute_image_list_entry.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_image_list_entry.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_image_list_entry`` resource creates and manages an Image List ## Example Usage -``` +```hcl resource "opc_compute_image_list" "test" { name = "imagelist1" description = "This is a description of the Image List" @@ -53,6 +53,6 @@ In addition to the above arguments, the following attributes are exported Image List's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_image_list_entry.entry1 example +```shell +$ terraform import opc_compute_image_list_entry.entry1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown b/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown index 881045b42..40dcd7167 100644 --- a/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown @@ -18,7 +18,7 @@ on your instance resources as an extra safety measure. ## Example Usage -``` +```hcl resource "opc_compute_ip_network" "test" { name = "internal-network" description = "Terraform Provisioned Internal Network" @@ -193,6 +193,6 @@ For example, in the Web Console an instance's fully qualified name is: The instance can be imported as such: -``` -terraform import opc_compute_instance.instance1 instance_name/instance_id +```shell +$ terraform import opc_compute_instance.instance1 instance_name/instance_id ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_address_association.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_address_association.html.markdown index 6b63ce55a..cffabad6a 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_address_association.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_address_association.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_ip_address_association`` resource creates and manages an IP ad ## Example Usage -``` +```hcl resource "opc_compute_ip_address_association" "default" { name = "PrefixSet1" ip_address_reservation = "${opc_compute_ip_address_reservation.default.name}" @@ -43,6 +43,6 @@ In addition to the above, the following variables are exported: IP Address Associations can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_ip_address_association.default example +```shell +$ terraform import opc_compute_ip_address_association.default example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_address_prefix_set.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_address_prefix_set.html.markdown index b4ff5c949..fa63f0794 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_address_prefix_set.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_address_prefix_set.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_ip_address_prefix_set`` resource creates and manages an IP add ## Example Usage -``` +```hcl resource "opc_compute_ip_address_prefix_set" "default" { name = "PrefixSet1" prefixes = ["192.168.0.0/16", "172.120.0.0/24"] @@ -40,6 +40,6 @@ In addition to the above, the following variables are exported: IP Address Prefix Set can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_ip_address_prefix_set.default example +```shell +$ terraform import opc_compute_ip_address_prefix_set.default example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown index 6a92b8cae..30aed5c62 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_ip_address_reservation`` resource creates and manages an IP ad ## Example Usage -``` +```hcl resource "opc_compute_ip_address_reservation" "default" { name = "IPAddressReservation1" ip_address_pool = "public-ippool" @@ -36,3 +36,11 @@ In addition to the above, the following attributes are exported: * `ip_address` - Reserved NAT IPv4 address from the IP address pool. * `uri` - The Uniform Resource Identifier of the ip address reservation + +## Import + +IP Address Reservations can be imported using the `resource name`, e.g. + +```shell +$ terraform import opc_compute_ip_address_reservation.default example +``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown index 8a7c073a2..8ed8334c6 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown @@ -13,7 +13,7 @@ an OPC identity domain, for the Shared Network. ## Example Usage -``` +```hcl resource "opc_compute_ip_association" "instance1_reservation1" { vcable = "${opc_compute_instance.test_instance.vcable}" parentpool = "ipreservation:${opc_compute_ip_reservation.reservation1.name}" @@ -41,6 +41,6 @@ The following attributes are exported: IP Associations can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_ip_association.association1 example +```shell +$ terraform import opc_compute_ip_association.association1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_network.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_network.html.markdown index 6a8885337..5b843219d 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_network.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_network.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_ip_network`` resource creates and manages an IP Network. ## Example Usage -``` +```hcl resource "opc_compute_ip_network" "foo" { name = "my-ip-network" description = "my IP Network" @@ -52,3 +52,11 @@ The following attributes are exported: * `public_napt_enabled` - Whether public internet access using NAPT for VNICs without any public IP Reservation or not. * `uri` - Uniform Resource Identifier for the IP Network + +## Import + +IP Networks can be imported using the `resource name`, e.g. + +```shell +$ terraform import opc_compute_ip_network.default example +``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_network_exchange.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_network_exchange.html.markdown index 0f07781f6..e0ab547b1 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_network_exchange.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_network_exchange.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_ip_network_exchange`` resource creates and manages an IP netwo ## Example Usage -``` +```hcl resource "opc_compute_ip_network_exchange" "default" { name = "NetworkExchange1" } @@ -32,6 +32,6 @@ The following arguments are supported: IP Network Exchange's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_ip_network_exchange.exchange1 example +```shell +$ terraform import opc_compute_ip_network_exchange.exchange1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown index 67632c92d..b1462261b 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_ip_reservation`` resource creates and manages an IP reservatio ## Example Usage -``` +```hcl resource "opc_compute_ip_reservation" "reservation1" { parent_pool = "/oracle/public/ippool" permanent = true @@ -38,6 +38,6 @@ deleted and recreated (if false). IP Reservations can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_ip_reservations.reservation1 example +```shell +$ terraform import opc_compute_ip_reservations.reservation1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_route.html.markdown b/website/source/docs/providers/opc/r/opc_compute_route.html.markdown index f7bfe7e63..ccb3d0dac 100644 --- a/website/source/docs/providers/opc/r/opc_compute_route.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_route.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_route`` resource creates and manages a route for an IP Network ## Example Usage -``` +```hcl resource "opc_compute_route" "foo" { name = "my-route" description = "my IP Network route" @@ -55,6 +55,6 @@ The following attributes are exported: Route's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_route.route1 example +```shell +$ terraform import opc_compute_route.route1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_sec_rule.html.markdown b/website/source/docs/providers/opc/r/opc_compute_sec_rule.html.markdown index 2593ad007..96a46b919 100644 --- a/website/source/docs/providers/opc/r/opc_compute_sec_rule.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_sec_rule.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_sec_rule`` resource creates and manages a sec rule in an OPC i ## Example Usage -``` +```hcl resource "opc_compute_sec_rule" "test_rule" { name = "test" source_list = "seclist:${opc_compute_security_list.sec-list1.name}" @@ -52,6 +52,6 @@ In addition to the above, the following values are exported: Sec Rule's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_sec_rule.rule1 example +```shell +$ terraform import opc_compute_sec_rule.rule1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_security_application.html.markdown b/website/source/docs/providers/opc/r/opc_compute_security_application.html.markdown index 0949f9467..2bf7fec5e 100644 --- a/website/source/docs/providers/opc/r/opc_compute_security_application.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_security_application.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_security_application`` resource creates and manages a security ## Example Usage (TCP) -``` +```hcl resource "opc_compute_security_application" "tomcat" { name = "tomcat" protocol = "tcp" @@ -22,7 +22,7 @@ resource "opc_compute_security_application" "tomcat" { ## Example Usage (ICMP) -``` +```hcl resource "opc_compute_security_application" "tomcat" { name = "tomcat" protocol = "icmp" @@ -52,6 +52,6 @@ The following arguments are supported: Security Application's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_security_application.application1 example +```shell +$ terraform import opc_compute_security_application.application1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_security_association.html.markdown b/website/source/docs/providers/opc/r/opc_compute_security_association.html.markdown index 0cbe442ef..2d711d589 100644 --- a/website/source/docs/providers/opc/r/opc_compute_security_association.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_security_association.html.markdown @@ -13,7 +13,7 @@ list in an OPC identity domain. ## Example Usage -``` +```hcl resource "opc_compute_security_association" "test_instance_sec_list_1" { name = "association1" vcable = "${opc_compute_instance.test_instance.vcable}" @@ -35,6 +35,6 @@ The following arguments are supported: Security Association's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_security_association.association1 example +```shell +$ terraform import opc_compute_security_association.association1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_security_ip_list.html.markdown b/website/source/docs/providers/opc/r/opc_compute_security_ip_list.html.markdown index 286ba5f9e..503c93efe 100644 --- a/website/source/docs/providers/opc/r/opc_compute_security_ip_list.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_security_ip_list.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_security_ip_list`` resource creates and manages a security IP ## Example Usage -``` +```hcl resource "opc_compute_security_ip_list" "sec_ip_list1" { name = "sec-ip-list1" ip_entries = ["217.138.34.4"] @@ -33,6 +33,6 @@ The following arguments are supported: IP List's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_ip_list.list1 example +```shell +$ terraform import opc_compute_ip_list.list1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_security_list.html.markdown b/website/source/docs/providers/opc/r/opc_compute_security_list.html.markdown index a7b84e692..461e6603e 100644 --- a/website/source/docs/providers/opc/r/opc_compute_security_list.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_security_list.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_security_list`` resource creates and manages a security list i ## Example Usage -``` +```hcl resource "opc_compute_security_list" "sec_list1" { name = "sec-list-1" policy = "permit" @@ -36,6 +36,6 @@ The following arguments are supported: Security List's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_security_list.list1 example +```shell +$ terraform import opc_compute_security_list.list1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_security_protocol.html.markdown b/website/source/docs/providers/opc/r/opc_compute_security_protocol.html.markdown index 46449a899..00208321a 100644 --- a/website/source/docs/providers/opc/r/opc_compute_security_protocol.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_security_protocol.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_security_protocol`` resource creates and manages a security pr ## Example Usage -``` +```hcl resource "opc_compute_security_protocol" "default" { name = "security-protocol-1" dst_ports = ["2045-2050"] @@ -60,6 +60,6 @@ In addition to the above, the following values are exported: ACL's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_security_protocol.default example +```shell +$ terraform import opc_compute_security_protocol.default example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_security_rule.html.markdown b/website/source/docs/providers/opc/r/opc_compute_security_rule.html.markdown index d2462980a..0a44150e7 100644 --- a/website/source/docs/providers/opc/r/opc_compute_security_rule.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_security_rule.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_security_rule`` resource creates and manages a security rule i ## Example Usage -``` +```hcl resource "opc_compute_security_rule" "default" { name = "SecurityRule1" flow_direction = "ingress" @@ -57,6 +57,6 @@ In addition to the above, the following attributes are exported: Security Rule's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_security_rule.rule1 example +```shell +$ terraform import opc_compute_security_rule.rule1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_ssh_key.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ssh_key.html.markdown index 2969ebea2..e982b935a 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ssh_key.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ssh_key.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_ssh_key`` resource creates and manages an SSH key in an OPC id ## Example Usage -``` +```hcl resource "opc_compute_ssh_key" "%s" { name = "test-key" key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqw6JwbjIk..." @@ -35,6 +35,6 @@ without removing it entirely from your Terraform resource definition. Defaults t SSH Key's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_ssh_key.key1 example +```shell +$ terraform import opc_compute_ssh_key.key1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown b/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown index a71a5b249..cfa19a2ad 100644 --- a/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown @@ -14,7 +14,7 @@ The ``opc_compute_storage_volume`` resource creates and manages a storage volume ## Example Usage -``` +```hcl resource "opc_compute_storage_volume" "test" { name = "storageVolume1" description = "Description for the Storage Volume" @@ -24,7 +24,7 @@ resource "opc_compute_storage_volume" "test" { ``` ## Example Usage (Bootable Volume) -``` +```hcl resource "opc_compute_image_list" "test" { name = "imageList1" description = "Description for the Image List" @@ -77,6 +77,6 @@ The following attributes are exported: Storage Volume's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_storage_volume.volume1 example +```shell +$ terraform import opc_compute_storage_volume.volume1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_storage_volume_snapshot.html.markdown b/website/source/docs/providers/opc/r/opc_compute_storage_volume_snapshot.html.markdown index 7a167080c..885739762 100644 --- a/website/source/docs/providers/opc/r/opc_compute_storage_volume_snapshot.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_storage_volume_snapshot.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_storage_volume_snapshot`` resource creates and manages a stora ## Example Usage -``` +```hcl resource "opc_compute_storage_volume_snapshot" "test" { name = "storageVolume1" description = "Description for the Storage Volume" @@ -54,6 +54,6 @@ In addition to the attributes above, the following attributes are exported: Storage Volume Snapshot's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_storage_volume_snapshot.volume1 example +```shell +$ terraform import opc_compute_storage_volume_snapshot.volume1 example ``` diff --git a/website/source/docs/providers/opc/r/opc_compute_vnic_set.html.markdown b/website/source/docs/providers/opc/r/opc_compute_vnic_set.html.markdown index c5cf9c455..191ffa159 100644 --- a/website/source/docs/providers/opc/r/opc_compute_vnic_set.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_vnic_set.html.markdown @@ -12,7 +12,7 @@ The ``opc_compute_vnic_set`` resource creates and manages a virtual NIC set in a ## Example Usage -``` +```hcl resource "opc_compute_vnic_set" "test_set" { name = "test_vnic_set" description = "My vnic set" @@ -40,6 +40,6 @@ The following arguments are supported: VNIC Set's can be imported using the `resource name`, e.g. -``` -terraform import opc_compute_vnic_set.set1 example +```shell +$ terraform import opc_compute_vnic_set.set1 example ``` diff --git a/website/source/docs/providers/template/r/dir.html.md b/website/source/docs/providers/template/r/dir.html.md new file mode 100644 index 000000000..9ce700826 --- /dev/null +++ b/website/source/docs/providers/template/r/dir.html.md @@ -0,0 +1,116 @@ +--- +layout: "template" +page_title: "Template: template_dir" +sidebar_current: "docs-template-resource-dir" +description: |- + Renders a directory of templates. +--- + +# template_dir + +Renders a directory containing templates into a separate directory of +corresponding rendered files. + +`template_dir` is similar to [`template_file`](../d/file.html) but it walks +a given source directory and treats every file it encounters as a template, +rendering it to a corresponding file in the destination directory. + +~> **Note** When working with local files, Terraform will detect the resource +as having been deleted each time a configuration is applied on a new machine +where the destination dir is not present and will generate a diff to create +it. This may cause "noise" in diffs in environments where configurations are +routinely applied by many different users or within automation systems. + +## Example Usage + +The following example shows how one might use this resource to produce a +directory of configuration files to upload to a compute instance, using +Amazon EC2 as a placeholder. + +```hcl +resource "template_dir" "config" { + source_dir = "${path.module}/instance_config_templates" + destination_dir = "${path.cwd}/instance_config" + + vars { + consul_addr = "${var.consul_addr}" + } +} + +resource "aws_instance" "server" { + ami = "${var.server_ami}" + instance_type = "t2.micro" + + connection { + # ...connection configuration... + } + + provisioner "file" { + # Referencing the template_dir resource ensures that it will be + # created or updated before this aws_instance resource is provisioned. + source = "${template_dir.config.destination_dir}" + destination = "/etc/myapp" + } +} + +variable "consul_addr" {} + +variable "server_ami" {} +``` + +## Argument Reference + +The following arguments are supported: + +* `source_dir` - (Required) Path to the directory where the files to template reside. + +* `destination_dir` - (Required) Path to the directory where the templated files will be written. + +* `vars` - (Optional) Variables for interpolation within the template. Note + that variables must all be primitives. Direct references to lists or maps + will cause a validation error. + +Any required parent directories of `destination_dir` will be created +automatically, and any pre-existing file or directory at that location will +be deleted before template rendering begins. + +After rendering this resource remembers the content of both the source and +destination directories in the Terraform state, and will plan to recreate the +output directory if any changes are detected during the plan phase. + +Note that it is _not_ safe to use the `file` interpolation function to read +files create by this resource, since that function can be evaluated before the +destination directory has been created or updated. It *is* safe to use the +generated files with resources that directly take filenames as arguments, +as long as the path is constructed using the `destination_dir` attribute +to create a dependency relationship with the `template_dir` resource. + +## Template Syntax + +The syntax of the template files is the same as +[standard interpolation syntax](/docs/configuration/interpolation.html), +but you only have access to the variables defined in the `vars` section. + +To access interpolations that are normally available to Terraform +configuration (such as other variables, resource attributes, module +outputs, etc.) you can expose them via `vars` as shown below: + +```hcl +resource "template_dir" "init" { + # ... + + vars { + foo = "${var.foo}" + attr = "${aws_instance.foo.private_ip}" + } +} +``` + +## Attributes + +This resource exports the following attributes: + +* `destination_dir` - The destination directory given in configuration. + Interpolate this attribute into other resource configurations to create + a dependency to ensure that the destination directory is populated before + another resource attempts to read it. diff --git a/website/source/docs/providers/ultradns/r/rdpool.html.markdown b/website/source/docs/providers/ultradns/r/rdpool.html.markdown index be7410fc1..80f9a3e55 100644 --- a/website/source/docs/providers/ultradns/r/rdpool.html.markdown +++ b/website/source/docs/providers/ultradns/r/rdpool.html.markdown @@ -33,8 +33,8 @@ The following arguments are supported: * `zone` - (Required) The domain to add the record to * `name` - (Required) The name of the record -* `order` - (Required) Ordering rule, one of FIXED, RANDOM or ROUND_ROBIN * `rdata` - (Required) list ip addresses. +* `order` - (Optional) Ordering rule, one of FIXED, RANDOM or ROUND_ROBIN. Default: 'ROUND_ROBIN'. * `description` - (Optional) Description of the Resource Distribution pool. Valid values are strings less than 256 characters. * `ttl` - (Optional) The TTL of the pool in seconds. Default: `3600`. diff --git a/website/source/docs/state/locking.html.md b/website/source/docs/state/locking.html.md index 99b635f4d..6a4b8648d 100644 --- a/website/source/docs/state/locking.html.md +++ b/website/source/docs/state/locking.html.md @@ -19,7 +19,7 @@ with the `-lock` flag but it is not recommended. If acquiring the lock is taking longer than expected, Terraform will output a status message. If Terraform doesn't output a message, state locking is -still occuring if your backend supports it. +still occurring if your backend supports it. Not all [backends](/docs/backends) support locking. Please view the list of [backend types](/docs/backends/types) for details on whether a backend diff --git a/website/source/layouts/alicloud.erb b/website/source/layouts/alicloud.erb index f6695b85c..b8cd55db3 100644 --- a/website/source/layouts/alicloud.erb +++ b/website/source/layouts/alicloud.erb @@ -10,7 +10,7 @@ Alicloud Provider - > + > Data Sources - > + > ECS Resources - > + > SLB Resources - > + > VPC Resources - > + > RDS Resources - > + > ESS Resources diff --git a/website/source/layouts/template.erb b/website/source/layouts/template.erb index 8416a3dc8..045e95811 100644 --- a/website/source/layouts/template.erb +++ b/website/source/layouts/template.erb @@ -21,6 +21,15 @@ + + > + Resources + + <% end %>